#if defined(ARCTIC)
#if (FEATURE_MODE == 0)
/**
 @file sys_tmm_ipfix.c

 @date 2019-7-2

 @version v1.0

 The file contains TMM IPFIX APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_ipfix.h"
#include "sys_usw_common.h"
#include "sys_usw_chip.h"
#include "sys_usw_ipfix.h"
#include "sys_usw_dma.h"
#include "sys_usw_register.h"
#include "drv_api.h"
#include "sys_usw_acl_api.h"
#include "sys_usw_xdata_api.h"

#define SYS_IPFIX_DUMP_FLOW_CNT 256
#define SYS_ALU_EXPORT_BMP 0xc
#define SYS_ALU_USE_32BITWISE 4
#define SYS_ALU_TWICE_16BITWISE_RECORD 2

#define BIT_WIDTH_32 32
#define BIT_WIDTH_16 16
#define CTC_IPFIX_FLOW_TRACK_PROFILE_ID_MAX 16
#define AD_16BIT_RESOURCE   8

#define SYS_IPFIX_CFG_ID_VEC_SIZE               256
#define SYS_IPFIX_CFG_ID_VEC_BLOCK_SIZE         16

#define SYS_USW_SET_HW_UDF_SHORT(lchip, dest, src)     \
    {\
        (dest)[2] = ((src)[8] << 8 | src[9]);                       \
        (dest)[1] = ((src)[6] << 24 | src[7] << 16 | src[4] << 8 | src[5]);           \
        (dest)[0] = ((src)[2] << 24 | src[3] << 16 | src[0] << 8 | src[1]);           \
    }

#define SYS_USW_SET_USR_UDF_SHORT(lchip, dest, src)     \
    {\
        (dest)[0] = ((src)[0]) >> 8;\
        (dest)[1] = ((src)[0]) ;\
        (dest)[2] = ((src)[0]) >> 24;\
        (dest)[3] = ((src)[0]) >> 16;\
        (dest)[4] = ((src)[1]) >> 8;\
        (dest)[5] = ((src)[1]) ;\
        (dest)[6] = ((src)[1]) >> 24;\
        (dest)[7] = ((src)[1]) >> 16;\
        (dest)[8] = ((src)[2]) >> 8;\
        (dest)[9] = ((src)[2]) ;\
    }

#define SYS_IPFIX_HASH_BUCKET_NUM 8*1024
#define SYS_IPFIX_FK_FIELD_NUM 8
#define SYS_SET_IPFIX_FK_FIELD(xdata_fk, data)\
    {\
        CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->set_fk_field(lchip, &xdata_fk, hash_key, (data)));\
    }
#define SYS_GET_IPFIX_FK_FIELD(xdata_fk, data)\
    {\
        ret = MCHIP_XDATA(lchip)->get_fk_field(lchip, &xdata_fk, hash_key, &(data));\
    }
#define SYS_VLAN_ID_CHECK(vlan_id)           \
    {                                            \
        if ((vlan_id) > CTC_MAX_VLAN_ID) {       \
            return CTC_E_BADID; } \
    }                                            \

extern sal_mutex_t*   p_ipfix_cb_mutex;
extern int32
_sys_usw_ipfix_unmapping_export_reason(uint8 lchip, uint8 sys_reason );
extern int32
_sys_usw_ipfix_unmapping_key_type(uint8 lchip, uint8 sys_key_type );
extern int32
_sys_usw_ipfix_decode_hashkey_ad(uint8 lchip, ctc_ipfix_data_t* p_data, uint8 is_ad, void* p_key);
extern int32
_sys_usw_ipfix_delete_entry_by_index(uint8 lchip, uint8 key_type, uint32 index, uint8 dir, uint8 is_key);
extern uint32
_sys_usw_ipfix_get_tbl_id_by_dir(uint8 lchip, uint32 tbl_id, uint8 dir);
extern uint32
_sys_usw_ipfix_get_tbl_id_by_type(uint8 lchip, uint8 key_type, uint8 dir);
extern int32
_sys_usw_ipfix_sample_interval_convert(uint8 lchip, sys_ipfix_sample_profile_t* p_profile, uint16* drv_interval );
extern int32
sys_usw_acl_get_udf_hit_index(uint8 lchip,  uint32 udf_id, uint16* udf_hit_index);

extern int32
sys_tmm_ipfix_set_bulk_timer_interval(uint8 lchip, uint32 ctc_bulk_interval);
extern int32
_sys_usw_ipfix_map_reason_sys_to_ctc_bmp(uint8 lchip, uint32 suppress_reason_bmp, uint32 deny_export_reason_bmp, ctc_ipfix_flow_cfg_t* p_flow_cfg);
extern int32
_sys_tmm_ipfix_get_drop_dir(uint16 reason_id, uint8* p_dir);
extern int32
_sys_usw_ipfix_map_reason_ctc_to_sys_bmp(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg, uint32 * suppress_reason_bmp, uint32 * deny_export_reason_bmp);
extern int32
_sys_tmm_ipfix_set_flow_drop_classid(uint8 lchip, void* ds0, void* ds1, ctc_ipfix_flow_cfg_t* p_flow_cfg);
extern int32
sys_usw_acl_get_udf_id(uint8 lchip, uint16 udf_hit_index, uint32* p_udf_id);
extern  int32
_sys_tmm_ipfix_set_v4_short_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern  int32
_sys_tmm_ipfix_set_v6_short_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
sys_tmm_ipfix_drop_clalssid_to_reason(uint8 lchip, uint32 drop_classid_bmp, uint32* ctc_drop_reaon_bmp, uint8 dir);
extern  uint8
_sys_tmm_ipfix_get_key_width(uint8 lchip, uint8 key_type);
extern int32
_sys_usw_ipfix_encode_l2_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_l2l3_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_ipv4_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_ipv6_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_encode_mpls_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data);
extern int32
_sys_usw_ipfix_mapping_ctc_to_sys_export_reason(uint8 lchip, uint8 ctc_reason);
extern int32
_sys_tmm_ipfix_get_drop_init_value(uint8 dir, uint32* p_drop_init_value);
extern int32
_sys_tmm_ipfix_get_timer_max_phy_ptr(uint8 lchip, uint32* p_max_phy_ptr);
extern int32
_sys_tmm_ipfix_get_timer_interval(uint8 lchip, uint8 is_bulk_tim, uint32* p_ctc_interval, uint32* p_sys_interval);
extern int32
_sys_tmm_ipfix_drop_classid_spool_init(uint8 lchip);
extern int32
_sys_tmm_ipfix_init_drop_reason(uint8 lchip);
extern int32
sys_tmm_ipfix_set_global_cfg(uint8 lchip, void* cfg);
extern int32
sys_usw_acl_get_udf_info(uint8 lchip,  uint32 udf_id, sys_acl_udf_info_t* p_udf_info);
extern int32
_sys_usw_ipfix_set_l2_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_l2l3_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_ipv4_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_ipv6_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_l2l3_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_set_mpls_hash_field_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_mac_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_l2l3_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_v4_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_v6_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern int32
_sys_usw_ipfix_get_mpls_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel);
extern uint16
sys_usw_port_api_get_lport_with_chan(uint8 lchip, uint8 rx, uint16 chan_id);
extern int32
sys_usw_vlan_get_vlan_range_by_maxvid(uint8 lchip, ctc_vlan_range_info_t * vrange_info, uint16 max_vid, bool is_svlan, ctc_vlan_range_t * p_vlan_range);
extern int32
_sys_at_ipfix_decode_flex_key(uint8 lchip, void* pdata, void* key);
extern int32
_sys_usw_ipfix_encode_hash(uint8 lchip, sys_ipfix_param_t* param);
extern uint8
sys_usw_l4_type_map(uint8 lchip, uint8 type, uint8 is_ctc2drv);

uint8 ctc_at_hash_type[]={
CTC_IPFIX_KEY_HASH_MAC,
CTC_IPFIX_KEY_HASH_MAC,
CTC_IPFIX_KEY_HASH_L2_L3,
CTC_IPFIX_KEY_HASH_IPV4,
CTC_IPFIX_KEY_HASH_IPV6,
CTC_IPFIX_KEY_HASH_MPLS,
CTC_IPFIX_KEY_HASH_IPV4_SINGLE,
CTC_IPFIX_KEY_HASH_IPV6_SINGLE,
CTC_IPFIX_KEY_HASH_UDF_SINGLE,
CTC_IPFIX_KEY_HASH_UDF,
CTC_IPFIX_KEY_HASH_IPV6,/*tmp ipv6 replace nsh*/
CTC_IPFIX_KEY_HASH_IPV6_SINGLE/*tmp ipv6 short replace nsh*/
};

uint8 sys_at_hash_type[]={
SYS_IPFIX_HASH_TYPE_L2,
SYS_IPFIX_HASH_TYPE_L2L3,
SYS_IPFIX_HASH_TYPE_IPV4,
SYS_IPFIX_HASH_TYPE_IPV6,
SYS_IPFIX_HASH_TYPE_MPLS,
SYS_IPFIX_HASH_TYPE_UDF,
SYS_IPFIX_HASH_TYPE_UDF_SHORT,
SYS_IPFIX_HASH_TYPE_IPV4_SHORT,
SYS_IPFIX_HASH_TYPE_IPV6_SHORT,
SYS_IPFIX_HASH_TYPE_IPV4_SHORT

};

uint8 ctc_at_export_reason[]={
CTC_IPFIX_NO_EXPORT,
CTC_IPFIX_REASON_EXPIRED,
CTC_IPFIX_REASON_TCP_CLOSE,
CTC_IPFIX_REASON_PACKET_CNT_OVERFLOW,
CTC_IPFIX_REASON_DROP_CNT_OVERFLOW,
CTC_IPFIX_REASON_NEW_FLOW_INSERT,
CTC_IPFIX_REASON_DROP_REASON_CHANGE,
CTC_IPFIX_REASON_LAST_TS_OVERFLOW,
CTC_IPFIX_REASON_JITTER_OVERFLOW,
CTC_IPFIX_REASON_LATENCY_OVERFLOW,
CTC_IPFIX_REASON_TTL_CHANGE,
CTC_IPFIX_REASON_BYTE_CNT_OVERFLOW,
CTC_IPFIX_REASON_DEST_CHANGE,
CTC_IPFIX_REASON_DUMP,
CTC_IPFIX_REASON_LATENCY_EVENT,
CTC_IPFIX_REASON_BURST_EVENT,
CTC_IPFIX_REASON_TC_MARK,
CTC_IPFIX_REASON_BUFFER_DROP,
CTC_IPFIX_NO_EXPORT,/*spec don't support buffer drop overflow*/
CTC_IPFIX_REASON_HASH_CONFLICT,
CTC_IPFIX_REASON_BURST_CNT_OVERFLOW,
CTC_IPFIX_REASON_LATENCY_CNT_OVERFLOW
};

struct alu_profile{
    uint32 logEn               :4;
    uint32 discardEn           :4;
    uint32 aluEn               :1;
    uint32 typeSel             :4;
    uint32 exportEn            :4;
    uint32 exportReason        :5;
    uint32 weight              :3;
    uint32 useAsAlu16          :1;
    uint32 cmp0LUseRd          :1;
    uint32 cmp1LUseRd          :1;
    uint32 cmp0SelL            :4;
    uint32 typeMask            :16;
    uint32 typeValue           :16;
    uint32 cmp1SelL            :4;
    uint32 cmp0SelR            :4;
    uint32 cmp1SelR            :4;
    uint32 cmp0Op              :3;
    uint32 cmp1Op              :3;
    uint32 cmp0Op1             :3;
    uint32 cmp1Op1             :3;
    uint32 dataOp              :4;
    uint32 dataOp1             :4;
    uint32 arg0                :32;
    uint32 arg1                :32;
    uint32 cmp0MaskL           :32;
    uint32 cmp1MaskL           :32;
    uint32 cmp0MaskR           :32;
    uint32 cmp1MaskR           :32;
    uint32 dataMaskR           :32;
    uint32 condOp              :2;
    uint32 dataSelR            :3;
    uint32 rsv                 :27;
};

enum alu_cmp_unit{
    SYS_ALU_CMP_FALSE = 0,
    SYS_ALU_CMP_GREATER_OR_EQUAL,
    SYS_ALU_CMP_LESS_OR_EQUAL,
    SYS_ALU_CMP_EQUAL,
    SYS_ALU_CMP_GREATER,
    SYS_ALU_CMP_LESS,
    SYS_ALU_CMP_NOT_EQUAL,
    SYS_ALU_CMP_TRUE
};
enum alu_operator_unit{
    SYS_ALU_DATA_DO_NOTING = 0,
    SYS_ALU_DATA_CALCULATE_EQUAL,
    SYS_ALU_DATA_ADD_TOGETHER,
    SYS_ALU_DATA_DEC_TOGETHER,
    SYS_ALU_DATA_CALCULATE_MAX,
    SYS_ALU_DATA_CALCULATE_MIN,
    SYS_ALU_DATA_CALCULATE_AVERAGE,
    SYS_ALU_DATA_CALCULATE_OR,
    SYS_ALU_DATA_CALCULATE_AND,
    SYS_ALU_DATA_CALCULATE_XOR,
    SYS_ALU_DATA_AUTO_INCREMENT,
    SYS_ALU_DATA_AUTO_DECREASE
};
enum alu_operation_unit{
    SYS_ALU_BITWISE_ST0_AND_ST0 = 0,
    SYS_ALU_BITWISE_ST0_OR_ST0,
    SYS_ALU_BITWISE_ST0_CONDOP,
    SYS_ALU_BITWISE_ST1_CONDOP
};

#define IPFIX_AT_TRAVERSE_TYPE_PROCESS(dump_info, key_type, is_remove,dir)\
        do{\
                ipfix_data.key_index = SYS_IPFIX_GET_ADINDEX(ipfix_data.key_index, dir);\
                    if(is_remove)\
                    {\
                        if(CTC_E_NONE == ((ctc_ipfix_traverse_remove_cmp)fn)(&ipfix_data, p_data->user_data))\
                        {\
                            _sys_usw_ipfix_delete_entry_by_index(lchip, key_type, ipfix_data.key_index,dir, 1);\
                            _sys_usw_ipfix_delete_entry_by_index(lchip, key_type, ipfix_data.key_index,dir, 0);\
                        }\
                    }\
                    else if(traverse_action == SYS_IPFIX_DUMP_ENYRY_INFO)\
                        {\
                            ((ctc_ipfix_traverse_fn)fn)(&ipfix_data, &dump_info);\
                        }\
                        else\
                        {\
                            ((ctc_ipfix_traverse_fn)fn)(&ipfix_data, p_data->user_data);\
                        }\
        }while(0)


int32
_sys_at_ipfix_get_export_reason_dir(uint16 reason_id, uint8* p_dir)
{
    uint8 dir = 0;

    switch (reason_id)
    {
    case CTC_IPFIX_REASON_PACKET_CNT_OVERFLOW:
    case CTC_IPFIX_REASON_BYTE_CNT_OVERFLOW:
    case CTC_IPFIX_REASON_DROP_CNT_OVERFLOW:
    case CTC_IPFIX_REASON_DROP_REASON_CHANGE:
    case CTC_IPFIX_REASON_EXPIRED:
    case CTC_IPFIX_REASON_TCP_CLOSE:
    case CTC_IPFIX_REASON_LAST_TS_OVERFLOW:
    case CTC_IPFIX_REASON_NEW_FLOW_INSERT:
    case CTC_IPFIX_REASON_DEST_CHANGE:
    case CTC_IPFIX_REASON_TTL_CHANGE:
    case CTC_IPFIX_REASON_TC_MARK:
    case CTC_IPFIX_REASON_BURST_EVENT:
        dir = CTC_BOTH_DIRECTION;
        break;
    case CTC_IPFIX_REASON_BUFFER_DROP:
       dir = CTC_INGRESS;
        break;
    case CTC_IPFIX_REASON_JITTER_OVERFLOW:
    case CTC_IPFIX_REASON_LATENCY_OVERFLOW:
    case CTC_IPFIX_REASON_LATENCY_EVENT:
    case CTC_IPFIX_REASON_LATENCY_CNT_OVERFLOW:
    case CTC_IPFIX_REASON_BURST_CNT_OVERFLOW :
    dir = CTC_EGRESS;
        break;
    case CTC_IPFIX_REASON_HASH_CONFLICT:
    case CTC_IPFIX_REASON_DUMP:
        return CTC_E_NOT_SUPPORT;
    default:
        break;
    }
    if(p_dir)
    {
        *p_dir = dir;
    }
    return CTC_E_NONE;
}

int16
_sys_usw_ipfix_map_mmu_reason_sys_to_ctc_bmp(uint8 lchip, uint16 reason_bmp, ctc_ipfix_data_t* p_data, uint8 dir)
{
    uint8 ctc_mmu_drop_reason_irm[]={
    CTC_QOS_BUFFER_PORT_PRIO_CLASS,
    CTC_QOS_BUFFER_PORT_SC,
    CTC_QOS_BUFFER_PORT,
    CTC_QOS_BUFFER_SC,
    CTC_QOS_BUFFER_CONTROL,
    CTC_QOS_BUFFER_C2C,
    CTC_QOS_BUFFER_TOTAL,
    };
    uint8 ctc_mmu_drop_reason_erm[]={
    CTC_QOS_BUFFER_QUEUE,
    CTC_QOS_BUFFER_PORT_SC,
    CTC_QOS_BUFFER_PORT,
    CTC_QOS_BUFFER_SC,
    CTC_QOS_BUFFER_CONTROL,
    CTC_QOS_BUFFER_C2C,
    CTC_QOS_BUFFER_TOTAL,
    CTC_QOS_BUFFER_NONE,
    CTC_QOS_BUFFER_QUEUE,
    CTC_QOS_BUFFER_PORT,
    };
    uint8 loop = 0;
    uint8* val = (dir? ctc_mmu_drop_reason_erm : ctc_mmu_drop_reason_irm);
    reason_bmp = (dir? (reason_bmp & 0x37f) : (reason_bmp & 0x7f));/*valid bits*/
    while (reason_bmp)
    {
        if (reason_bmp & 1)
        {
            CTC_BIT_SET(p_data->buf_drop_reason[dir], val[loop]);
        }
        reason_bmp = reason_bmp >> 1;
        loop++;
    }

    return CTC_E_NONE;
}


int32
_sys_at_ipfix_xalu_profile_spool_init(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    ctc_spool_t spool;

    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = CTC_IPFIX_FLOW_TRACK_PROFILE_ID_MAX;
    spool.max_count = CTC_IPFIX_FLOW_TRACK_PROFILE_ID_MAX;
    spool.user_data_size = sizeof(sys_ipfix_xalu_profile_t);
    spool.key_size = CTC_OFFSET_OF(sys_ipfix_xalu_profile_t, calc_key_len);
    spool.min_index = 0;
    spool.max_index = CTC_IPFIX_FLOW_TRACK_PROFILE_ID_MAX-1;

    /*create xalu type spool*/
    spool.desc = "opf-ipfix-xalu-profile";
    p_usw_ipfix_master[lchip]->xalu_spool= ctc_spool_create(&spool);
    if (NULL == p_usw_ipfix_master[lchip]->xalu_spool)
    {
        ret =  CTC_E_NO_MEMORY;
    }

    return ret;
}

int32
sys_at_ipfix_init_register(uint8 lchip, void* p_global_cfg)
{
    uint16 loop_i = 0;
    uint32 entry_num = 0;
    uint32 cmd = 0;
    uint32 byte_cnt[2] = {0};
    uint32 value_a = 0;
    uint32 max_phy_ptr = 0;
    ds_t epe_acl_qos_ctl;
    uint32 ipfixftm = 0;
    uint8 fld_id = 0;
#ifndef EMULATION_ENV
    uint32 ctc_export_interval = 100; /*default value: 100ms */
    uint32 sys_export_interval = 0;
#endif
    uint32 flow_change_cnt_mask[8] = {0};
    ctc_ipfix_global_cfg_t ipfix_cfg;
    drv_work_platform_type_t platform_type;
    IpfixHashLookupCtl_m ipfix_hash;
    IpeFwdFlowHashCtl_m  ipfix_flow_hash;
    IpfixEngineCtl0_m      ipfix_ctl;
    IpePreLookupFlowCtl_m lookup_ctl;
    IpfixFlushTimerCtl_m flush_tim_ctl;
    IpfixAgingTimerCtl_m aging_tim_ctl;
    IpfixEngineMmuCtl_m mmu_ctl;
    IpfixAgingTimerMmuAdMaskCtl_m mmu_ad_mask_ctl;

    sal_memset(&ipfix_cfg, 0, sizeof(ctc_ipfix_global_cfg_t));
    sal_memset(&ipfix_hash, 0, sizeof(IpfixHashLookupCtl_m));
    sal_memset(&ipfix_flow_hash, 0, sizeof(ipfix_flow_hash));
    sal_memset(&ipfix_ctl, 0, sizeof(IpfixEngineCtl0_m));
    sal_memset(&lookup_ctl, 0, sizeof(IpePreLookupFlowCtl_m));
    sal_memset(&flush_tim_ctl, 0, sizeof(flush_tim_ctl));
    sal_memset(&aging_tim_ctl, 0, sizeof(aging_tim_ctl));
    sal_memset(&mmu_ctl, 0, sizeof(mmu_ctl));
    sal_memset(&mmu_ad_mask_ctl, 0, sizeof(mmu_ad_mask_ctl));

    /*MMU config*/
    SetIpfixEngineMmuCtl(V, maxQueCntExportThreCheckEn_f, &mmu_ctl, 0);
    SetIpfixEngineMmuCtl(V, minQueCntExportThreCheckEn_f, &mmu_ctl, 0);
    SetIpfixEngineMmuCtl(V, maxQueCntExportThrd_f, &mmu_ctl, 0x3FFFF);
    SetIpfixEngineMmuCtl(V, minQueCntExportThrd_f, &mmu_ctl, 0xFFFF);
    SetIpfixEngineMmuCtl(V, maxMbInstantThrd_f, &mmu_ctl, 0x10);
    cmd = DRV_IOW( IpfixEngineMmuCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mmu_ctl));

    SetIpfixAgingTimerMmuAdMaskCtl(V, mmuEventAdMask_mbInstantCnt_f, &mmu_ad_mask_ctl, 0xFF);
    SetIpfixAgingTimerMmuAdMaskCtl(V, mmuEventAdMask_burstState_f, &mmu_ad_mask_ctl, 1);
    SetIpfixAgingTimerMmuAdMaskCtl(V, mmuEventAdMask_minQueueCnt_f, &mmu_ad_mask_ctl, 0x7FF);
    SetIpfixAgingTimerMmuAdMaskCtl(V, mmuEventAdMask_maxQueueCnt_f, &mmu_ad_mask_ctl, 0x3FFFF);
    SetIpfixAgingTimerMmuAdMaskCtl(V, mmuEventAdMask_flowChangeCnt_f, &mmu_ad_mask_ctl, 0xF);
    SetIpfixAgingTimerMmuAdMaskCtl(V, mmuEventAdMask_valid_f, &mmu_ad_mask_ctl, 0x1);

    cmd = DRV_IOW( IpfixAgingTimerMmuAdMaskCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mmu_ad_mask_ctl));

    sys_usw_ftm_query_table_entry_num(lchip,IpfixAgingTimerAdMaskCtl0_t,&entry_num);
    value_a = 0xF;
    cmd = DRV_IOW(IpfixAgingTimerAdMaskCtl0_t, IpfixAgingTimerAdMaskCtl0_flowChangeCnt_f);
    for (loop_i = 0; loop_i < entry_num; loop_i++)
    {
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, loop_i, DRV_CMD_PP_EN(cmd), &value_a));
    }
    /* flowChangeCnt (0, 5, 4)  4bit  valid(0,0,1) 1bit*/
    flow_change_cnt_mask[0] = (SYS_GET_CHIP_VERSION == SYS_CHIP_SUB_VERSION_A)? 0x1E1 : 0x1E0;

    drv_get_platform_type(lchip, &platform_type);

    /*p_global_cfg is NULL, using default config, else using user define */
    sal_memcpy(&ipfix_cfg, p_global_cfg, sizeof(ctc_ipfix_global_cfg_t));

    SetIpfixEngineCtl(V, bypassUpdateOp_f, &ipfix_ctl, 0);
    byte_cnt[0] = (ipfix_cfg.bytes_cnt) & 0xffffffff;
    byte_cnt[1] = (ipfix_cfg.bytes_cnt >> 32) & 0x1f;

    SetIpfixEngineCtl(A, byteCntWraparoundThre_f, &ipfix_ctl, byte_cnt);  /* pl special process */

    if(ipfix_cfg.conflict_export)
    {
        value_a = 1;
        cmd = DRV_IOW(IpeFwdCtl_t, IpeFwdCtl_ipfixConflictPktLogEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    }
    ipfix_cfg.pkt_cnt = (ipfix_cfg.pkt_cnt == 0)?0:(ipfix_cfg.pkt_cnt - 1);
    SetIpfixEngineCtl(V, pktCntWraparoundThre_f , &ipfix_ctl, ipfix_cfg.pkt_cnt); /* pl special process */
    SetIpfixEngineCtl(V, enableRecordMissPktCnt_f , &ipfix_ctl, 1);
    SetIpfixEngineCtl(V, isCpuSetFlowKeyMode_f , &ipfix_ctl, 0);
    SetIpfixEngineCtl(V, ignorTcpClose_f , &ipfix_ctl, 0);
    SetIpfixEngineCtl(V, tsWrapAroundThre_f , &ipfix_ctl, ipfix_cfg.times_interval);  /*1s*/  /* pl special process */
    SetIpfixEngineCtl(V, unknownPktDestIsVlanId_f, &ipfix_ctl, 0);
    SetIpfixEngineCtl(V, dropPktCntWrapAroundThrd0_f, &ipfix_ctl, 0x3FF);  /* init max value */
    SetIpfixEngineCtl(V, dropPktCntWrapAroundThrd1_f, &ipfix_ctl, 0x3FF);
    SetIpfixEngineCtl(V, maxLatencyExportThreshold_f, &ipfix_ctl, 0xFFFFFFFF);
    SetIpfixEngineCtl(V, maxJitterExportThreshold_f, &ipfix_ctl, 0xFFFF);

    SetIpfixEngineCtl(V, ttlChangeUpdateLastTtlField_f, &ipfix_ctl, 1); /* for update ttl*/
    SetIpfixEngineCtl(V, bcastPktDestIsVlanId_f, &ipfix_ctl, 1);        /* default use vsiid, not mcastgroupid */
    SetIpfixEngineCtl(V, instantPushDmaBmp_f, &ipfix_ctl, 0x80000);
    SetIpfixEngineCtl(V, dropFlagMask_f, &ipfix_ctl, 0x3);              /* for CTC_IPFIX_REASON_TC_MARK*/
    SetIpfixEngineCtl(V, firstDropPktTriggerEventEn_f, &ipfix_ctl, 1);   /* for CTC_IPFIX_REASON_DROP_REASON_CHANGE*/

    SetIpfixEngineCtl(V, latencyCareDiscard_f, &ipfix_ctl, 0);
    SetIpfixEngineCtl(V, hashConflictPushDma_f, &ipfix_ctl, 0);
    SetIpfixEngineCtl(V, dropCheckEnMask_f , &ipfix_ctl, 0);/* for CTC_IPFIX_REASON_TC_MARK*/
    SetIpfixEngineCtl(V, latencyCongestReportEn_f , &ipfix_ctl, 1);
    SetIpfixEngineCtl(V, microBurstReportEn_f , &ipfix_ctl, 1);

    cmd = DRV_IOR( IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_flow_hash));
    SetIpeFwdFlowHashCtl(V, ipfixDestUseApsGroupId_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, ipfixDestUseEcmpGroupId_f , &ipfix_flow_hash,0);
    SetIpeFwdFlowHashCtl(V, ipfixHashBackToL3V6Type_f , &ipfix_flow_hash, 1);
    SetIpeFwdFlowHashCtl(V, ipfixHashL2L3ForcebackL2Type_f , &ipfix_flow_hash, 0x3);
    SetIpeFwdFlowHashCtl(V, ipfixHashL2L3ForcebackL3Type_f , &ipfix_flow_hash, 1);

    /*set merge global control */
    cmd = DRV_IOR( IpePreLookupFlowCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &lookup_ctl));
    SetIpePreLookupFlowCtl(V, flowVxlanFlowKeyL4UseOuter_f, &lookup_ctl, 1);
    SetIpePreLookupFlowCtl(V, flowGreFlowKeyL4UseOuter_f  , &lookup_ctl, 1);

    /* ipfix mirror*/
    value_a = 1;
    cmd = DRV_IOW( IpeFwdCtl_t, IpeFwdCtl_ipfixMirrorPktLogEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    /*span pkt do ipfix*/
    value_a = 1;
    cmd = DRV_IOW( EpeHdrAdjSpanCtl_t, EpeHdrAdjSpanCtl_spanOnDropSpanPktUnset_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    /* egress vrfid*/
    value_a = 1;
    cmd = DRV_IOW( IpeFwdCtl_t, IpeFwdCtl_vrfIdShareEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    cmd = DRV_IOW( EpeHdrAdjustCtl_t, EpeHdrAdjustCtl_vrfIdShareEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

    /*not statistic stacking packet header*/
    value_a = 16;
    cmd = DRV_IOW( EpeHeaderEditCtl_t, EpeHeaderEditCtl_fabricIpfixSkipCloudHdrLen_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    value_a = 1;
    cmd = DRV_IOW( EpeHeaderEditCtl_t, EpeHeaderEditCtl_fabricIpfixSkipCflexHdr_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));

     /*IPFix hash ctl*/
    ipfixftm=SYS_FTM_SPEC(lchip, CTC_FTM_SPEC_IPFIX);

    SetIpfixHashLookupCtl(V, ipfixLevel0HashEn_f, &ipfix_hash, 1);
    SetIpfixHashLookupCtl(V, ipfixLevel1HashEn_f, &ipfix_hash, (ipfixftm > SYS_IPFIX_HASH_BUCKET_NUM));
    SetIpfixHashLookupCtl(V, ipfixLevel2HashEn_f, &ipfix_hash, (ipfixftm > SYS_IPFIX_HASH_BUCKET_NUM*2));
    SetIpfixHashLookupCtl(V, ipfixLevel3HashEn_f, &ipfix_hash, (ipfixftm > SYS_IPFIX_HASH_BUCKET_NUM*3));

   /* aging and export timer */
    cmd = DRV_IOR(IpfixAgingTimerCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_tim_ctl));
    SetIpfixAgingTimerCtl(V, agingUpdEn_f, &aging_tim_ctl, 1);  /* Timer Enable */
    /* flowChangeCnt (0, 5, 4)  4bit */
    SetIpfixAgingTimerCtl(A, removeIngressAdMask_f , &aging_tim_ctl, flow_change_cnt_mask);
    SetIpfixAgingTimerCtl(A, removeEgressAdMask_f , &aging_tim_ctl, flow_change_cnt_mask);
    CTC_ERROR_RETURN(_sys_tmm_ipfix_get_timer_max_phy_ptr(lchip, &max_phy_ptr));
    SetIpfixAgingTimerCtl(V, agingMaxPtr_f , &aging_tim_ctl, max_phy_ptr);
    SetIpfixAgingTimerCtl(V, agingMinPtr_f , &aging_tim_ctl, 0);
    SetIpfixAgingTimerCtl(V, agingPhyMaxPtr_f , &aging_tim_ctl, max_phy_ptr);
    SetIpfixAgingTimerCtl(V, exportClearDiscardVectorBmp0_f , &aging_tim_ctl, 0xFFFFFFFF);
#ifndef EMULATION_ENV
    CTC_ERROR_RETURN(_sys_tmm_ipfix_get_timer_interval(lchip, 0, &ctc_export_interval, &sys_export_interval)); /*default value: 100ms */
    SetIpfixAgingTimerCtl(V, agingInterval_f, &aging_tim_ctl, sys_export_interval);
#endif

    /* flush and dump timer */
    cmd = DRV_IOR(IpfixFlushTimerCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl));
    SetIpfixFlushTimerCtl(V, forceFlushReasonExport_f , &flush_tim_ctl, 1);
    SetIpfixFlushTimerCtl(V, operationOneRound_f , &flush_tim_ctl, 1);
    SetIpfixFlushTimerCtl(V, flushCount_f , &flush_tim_ctl, max_phy_ptr);
    SetIpfixFlushTimerCtl(V, dmaFullStop_f , &flush_tim_ctl, 1);
    SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, flow_change_cnt_mask);
    SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, flow_change_cnt_mask);
    SetIpfixFlushTimerCtl(V, maxPtr_f , &flush_tim_ctl, max_phy_ptr);
    SetIpfixFlushTimerCtl(V, minPtr_f , &flush_tim_ctl, 0);
    SetIpfixFlushTimerCtl(V, phyMaxPtr_f , &flush_tim_ctl, max_phy_ptr);
    SetIpfixFlushTimerCtl(V, flushInterval_f, &flush_tim_ctl, 1000);/*default 1000 ticks trigger dump 480 bits*/
    if (platform_type == HW_PLATFORM)
    {
        #ifdef EMULATION_ENV
        SetIpfixFlushTimerCtl(V, flushInterval_f, &flush_tim_ctl, 100);    /* Emulation  special process due to fre down */
        #endif
    }

    cmd = DRV_IOW( IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_flow_hash));
    cmd = DRV_IOW( IpfixHashLookupCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_hash));
    cmd = DRV_IOW( IpfixHashLookupCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_hash));
    cmd = DRV_IOW( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    cmd = DRV_IOW( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl));
    cmd = DRV_IOW( IpePreLookupFlowCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &lookup_ctl));

    SetIpfixAgingTimerCtl(V, direction_f , &aging_tim_ctl, 0);
    SetIpfixAgingTimerCtl(V, mmuEn_f , &aging_tim_ctl, 1);
    for (fld_id = IpfixAgingTimerCtl_fifoThrd_0_value_f; fld_id <= IpfixAgingTimerCtl_fifoThrd_31_value_f; fld_id++)
    {
        DRV_SET_FIELD_VALUE(lchip, IpfixAgingTimerCtl_t, fld_id, &aging_tim_ctl, 0x3F);
    }
    DRV_SET_FIELD_VALUE(lchip, IpfixAgingTimerCtl_t,
                        IpfixAgingTimerCtl_fifoThrd_0_value_f + DRV_CONST(DRV_IPFIX_EXPORTREASON_HASH_CONFLICT_EXPORT), &aging_tim_ctl, 0x10);

    cmd = DRV_IOW( IpfixAgingTimerCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_tim_ctl));
    SetIpfixAgingTimerCtl(V, direction_f , &aging_tim_ctl, 1);
    SetIpfixAgingTimerCtl(V, mmuEn_f , &aging_tim_ctl, 0);
    cmd = DRV_IOW( IpfixAgingTimerCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &aging_tim_ctl));


    SetIpfixFlushTimerCtl(V, direction_f , &flush_tim_ctl, 0);
    SetIpfixFlushTimerCtl(V, mmuEn_f , &flush_tim_ctl, 1);
    for (fld_id = IpfixFlushTimerCtl_fifoThrd_0_value_f; fld_id <= IpfixFlushTimerCtl_fifoThrd_31_value_f; fld_id++)
    {
        DRV_SET_FIELD_VALUE(lchip, IpfixFlushTimerCtl_t, fld_id, &flush_tim_ctl, 0x10);
    }
    cmd = DRV_IOW( IpfixFlushTimerCtl0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl));
    SetIpfixFlushTimerCtl(V, mmuEn_f , &flush_tim_ctl, 0);
    SetIpfixFlushTimerCtl(V, direction_f , &flush_tim_ctl, 1);
    cmd = DRV_IOW( IpfixFlushTimerCtl1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl));
    sal_memset(&epe_acl_qos_ctl, 0, sizeof(epe_acl_qos_ctl));
    cmd = DRV_IOR(EpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_acl_qos_ctl));
    SetEpeAclQosCtl(V, ipfixHashBackToL3V6Type_f, &epe_acl_qos_ctl, 1);
    SetEpeAclQosCtl(V, ipfixHashL2L3ForcebackL2Type_f, &epe_acl_qos_ctl, 0x3);
    SetEpeAclQosCtl(V, ipfixHashL2L3ForcebackL3Type_f, &epe_acl_qos_ctl, 1);
    /*egress metadata*/
    SetEpeAclQosCtl(V, flowVxlanFlowKeyL4UseOuter_f, &epe_acl_qos_ctl, 1);
    SetEpeAclQosCtl(V, flowGreFlowKeyL4UseOuter_f, &epe_acl_qos_ctl, 1);
    SetEpeAclQosCtl(V, isNvgre_f, &epe_acl_qos_ctl, 1);
    cmd = DRV_IOW( EpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &epe_acl_qos_ctl));
    p_usw_ipfix_master[lchip]->xalu_vec = ctc_vector_init(CTC_VEC_BLOCK_NUM(SYS_IPFIX_CFG_ID_VEC_SIZE, SYS_IPFIX_CFG_ID_VEC_BLOCK_SIZE),SYS_IPFIX_CFG_ID_VEC_BLOCK_SIZE);
    if (NULL == p_usw_ipfix_master[lchip]->xalu_vec)/*xalu vector*/
    {
        return CTC_E_INIT_FAIL;
    }
    CTC_ERROR_RETURN(_sys_at_ipfix_xalu_profile_spool_init(lchip));/*xalu spool*/
    CTC_ERROR_RETURN(_sys_tmm_ipfix_drop_classid_spool_init(lchip));
    CTC_ERROR_RETURN(_sys_tmm_ipfix_init_drop_reason(lchip));

    CTC_ERROR_RETURN(sys_tmm_ipfix_set_global_cfg(lchip,p_global_cfg));
    MCHIP_CAP(SYS_CAP_IPFIX_AD_NUM) = max_phy_ptr+1;

    return CTC_E_NONE;
}



int32
sys_at_ipfix_set_property(uint8 lchip, void* cfg)
{
    uint32 cmd = 0;
    uint32 ad_mask[8] = {0};
    ctc_ipfix_bulk_op_t* p_bulk_op = NULL;
    ctc_ipfix_mburst_thrd_t* pro_mburst = NULL;
    uint32 ipfix_entry_num = 0;
    uint32 cfg_table_id = 0;
    IpfixFlushTimerCtl_m flush_tim_ctl;
    IpfixFlushTimerUpdateCtl_m flush_ud_ctl;
    IpfixFlushMissDmaFifoFullCount_m miss_cnt;
    IpfixEngineMmuCtl_m mmu_ctl;
    IpfixEngineCtl0_m      ipfix_ctl0;
    IpfixEngineCtl1_m      ipfix_ctl1;
    IpeFwdFlowHashCtl_m    ipe_fwd_flow_ctl;
    uint32 prof_id_bmp[8]={0};
    uint8 dir = 0;      
    uint32 max_phy_ptr =0;
    uint32 field_value;
    ctc_ipfix_property_t *p_ipfix_prop = (ctc_ipfix_property_t*)cfg;
    pro_mburst = (ctc_ipfix_mburst_thrd_t*)(p_ipfix_prop->value);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(cfg);
    sal_memset(&flush_tim_ctl, 0, sizeof(flush_tim_ctl));

    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL3Ipv4ShortHashKey_t, &ipfix_entry_num));/* get 120bits bits entry num */

    switch(p_ipfix_prop->type)
    {
    case CTC_IPFIX_PROP_BULK_OP:
        p_bulk_op = (ctc_ipfix_bulk_op_t*)p_ipfix_prop->value;
        if (!p_bulk_op->p_param)
        {
            return CTC_E_INVALID_PARAM;
        }

        dir = p_bulk_op->p_param->dir;
        cfg_table_id = (CTC_INGRESS == dir)? IpfixFlushTimerCtl0_t : IpfixFlushTimerCtl1_t;
        cmd = DRV_IOR(cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl));

        if(CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_BY_PROF))
        {
            SetIpfixFlushTimerCtl(V, operationBasedOnProfileIdMatch_f, &flush_tim_ctl, 1);
            if (0 == sal_memcmp(p_bulk_op->prof_id_bmp, prof_id_bmp, sizeof(prof_id_bmp)))
            {
                CTC_BMP_SET(prof_id_bmp, p_bulk_op->prof_id);
                SetIpfixFlushTimerCtl(A, profileIdBitmap_f, &flush_tim_ctl, prof_id_bmp);
            }
            else
            {
                SetIpfixFlushTimerCtl(A, profileIdBitmap_f, &flush_tim_ctl, p_bulk_op->prof_id_bmp);
            }
        }
        else
        {
            SetIpfixFlushTimerCtl(V, operationBasedOnProfileIdMatch_f, &flush_tim_ctl, 0);
        }
        if(CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN)&& !CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN))
        {/* only dump */
            SetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, disableFlushFlowToDma_f, &flush_tim_ctl, 0);
            /* revise for rtl bug */
            sal_memset(ad_mask, 0xff, sizeof(ad_mask));
            SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, ad_mask);
            SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, ad_mask);
        }
        else if(!CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN)&& CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN))
        {/* only flush */
            SetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, disableFlushFlowToDma_f, &flush_tim_ctl, 0);
            /* revise for rtl bug */
            sal_memset(ad_mask, 0, sizeof(ad_mask));
            ad_mask[0] = 0x1E0;/* keep flowChangeCnt value when remove entry */
            SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, ad_mask);
            SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, ad_mask);
        }
        else if(CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN)&& CTC_IS_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN))
        {/* dump and flush */
            SetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl, 0);
            SetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl, 1);
            SetIpfixFlushTimerCtl(V, disableFlushFlowToDma_f, &flush_tim_ctl, 0);
            /* revise for rtl bug */
            sal_memset(ad_mask, 0, sizeof(ad_mask));
            ad_mask[0] = 0x1E0;/* keep flowChangeCnt value when remove entry */
            SetIpfixFlushTimerCtl(A, flushFlowUpdateEgrAdMask_f , &flush_tim_ctl, ad_mask);
            SetIpfixFlushTimerCtl(A, flushFlowUpdateIngAdMask_f , &flush_tim_ctl, ad_mask);
        }
        if (p_bulk_op->p_param->start_index)
        {
            SetIpfixFlushTimerCtl(V, minPtr_f, &flush_tim_ctl, p_bulk_op->p_param->start_index);
        }
        else
        {
            SetIpfixFlushTimerCtl(V, minPtr_f, &flush_tim_ctl, 0);
        }
        if (p_bulk_op->p_param->entry_num)
        {
            SetIpfixFlushTimerCtl(V, flushCount_f, &flush_tim_ctl, p_bulk_op->p_param->entry_num);
            p_usw_ipfix_master[lchip]->dump_num = p_bulk_op->p_param->entry_num;
        }
        else
        {
            CTC_ERROR_RETURN(_sys_tmm_ipfix_get_timer_max_phy_ptr(lchip, &max_phy_ptr));
            SetIpfixFlushTimerCtl(V, flushCount_f, &flush_tim_ctl, max_phy_ptr);            
        }

        cmd = DRV_IOW( cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl));
        cfg_table_id = (dir == CTC_INGRESS)? IpfixFlushTimerUpdateCtl0_t : IpfixFlushTimerUpdateCtl1_t;
        cmd = DRV_IOR(cfg_table_id , DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_ud_ctl));

        sal_memset(&miss_cnt, 0, sizeof(IpfixFlushMissDmaFifoFullCount_m));
        cmd = DRV_IOW(IpfixFlushMissDmaFifoFullCount0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &miss_cnt));
        cmd = DRV_IOW(IpfixFlushMissDmaFifoFullCount1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &miss_cnt));

        SetIpfixFlushTimerUpdateCtl(V, flowEntryCount_f, &flush_ud_ctl, 0);
        if(!GetIpfixFlushTimerUpdateCtl(V, updEn_f, &flush_ud_ctl))
        {
            SetIpfixFlushTimerUpdateCtl(V, updEn_f, &flush_ud_ctl, 1);
        }
        else
        {
            return CTC_E_NOT_READY;
        }
        SetIpfixFlushTimerUpdateCtl(V, dmaIsFull_f, &flush_ud_ctl, 0);
        cmd = DRV_IOW(cfg_table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_ud_ctl));
        break;
    case CTC_IPFIX_PROP_MBURST:
        /*MMU config*/
        CTC_MAX_VALUE_CHECK(pro_mburst->mburst_off_thrd, pro_mburst->mburst_on_thrd);
        cmd = DRV_IOR( IpfixEngineMmuCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mmu_ctl));
        SetIpfixEngineMmuCtl(V, maxQueCntExportThreCheckEn_f, &mmu_ctl, pro_mburst->mburst_cnt_thrd?1:0);
        SetIpfixEngineMmuCtl(V, minQueCntExportThreCheckEn_f, &mmu_ctl, pro_mburst->mburst_cnt_thrd?1:0);
        SetIpfixEngineMmuCtl(V, maxQueCntExportThrd_f, &mmu_ctl, pro_mburst->mburst_cnt_thrd?pro_mburst->mburst_on_thrd:0x3FFFF);
        SetIpfixEngineMmuCtl(V, minQueCntExportThrd_f, &mmu_ctl, pro_mburst->mburst_cnt_thrd?pro_mburst->mburst_off_thrd:0xFFFF);
        SetIpfixEngineMmuCtl(V, maxMbInstantThrd_f, &mmu_ctl, pro_mburst->mburst_cnt_thrd);
        cmd = DRV_IOW( IpfixEngineMmuCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mmu_ctl));
        break;
    case CTC_IPFIX_PROP_HASH_CONFLICT_THRD:
        field_value = *(uint32*)(p_ipfix_prop->value);
        CTC_MAX_VALUE_CHECK(field_value,0x1FFF);
        cmd = DRV_IOR(IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl0));
        SetIpfixEngineCtl0(V, hashConflictThrd_f , &ipfix_ctl0, field_value);
        SetIpfixEngineCtl0(V, hashConflictPushDma_f , &ipfix_ctl0, !!field_value);
        cmd = DRV_IOW( IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl0));

        cmd = DRV_IOR(IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl1));
        SetIpfixEngineCtl1(V, hashConflictThrd_f , &ipfix_ctl1, field_value);
        SetIpfixEngineCtl1(V, hashConflictPushDma_f , &ipfix_ctl1, !!field_value);
        cmd = DRV_IOW( IpfixEngineCtl1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl1));
        break;
    case CTC_IPFIX_PROP_LOW_LATENCY:
        field_value = *(uint32*)(p_ipfix_prop->value);
        cmd = DRV_IOR(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl));
        SetIpeFwdFlowHashCtl(V, bypassIpfixResult_f , &ipe_fwd_flow_ctl, !!field_value);
        cmd = DRV_IOW( IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl));
        break;
    default:
    break;
    }
    return CTC_E_NONE;
}

int32
sys_at_ipfix_get_property(uint8 lchip, void* cfg)
{
    uint32 cmd = 0;
    ctc_ipfix_bulk_op_t* p_bulk_op = NULL;
    ctc_ipfix_bulk_op_miss_t* p_bulk_op_miss = NULL;
    ctc_ipfix_mburst_thrd_t* pro_mburst = NULL;
    IpfixEngineMmuCtl_m mmu_ctl;
    IpfixFlushTimerCtl_m flush_tim_ctl;
    IpfixFlushTimerUpdateCtl_m flush_tim_up_ctl;
    IpfixFlushMissDmaFifoFullCount_m dump_miss_cnt;
    IpfixEngineCtl0_m      ipfix_ctl0;
    IpeFwdFlowHashCtl_m    ipe_fwd_flow_ctl;
    uint32 tbl_id = 0;
    ctc_ipfix_property_t *p_ipfix_prop = (ctc_ipfix_property_t*)cfg;
    pro_mburst = (ctc_ipfix_mburst_thrd_t*)(p_ipfix_prop->value);
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(cfg);
    sal_memset(&flush_tim_ctl, 0, sizeof(flush_tim_ctl));
    sal_memset(&flush_tim_up_ctl, 0, sizeof(flush_tim_up_ctl));
    sal_memset(&dump_miss_cnt, 0, sizeof(dump_miss_cnt));

    switch(p_ipfix_prop->type)
    {
    case CTC_IPFIX_PROP_BULK_OP:
        p_bulk_op = (ctc_ipfix_bulk_op_t*)p_ipfix_prop->value;
        if (!p_bulk_op->p_param)
        {
            return CTC_E_INVALID_PARAM;
        }
        tbl_id = (p_bulk_op->p_param->dir == CTC_INGRESS)? IpfixFlushTimerCtl0_t : IpfixFlushTimerCtl1_t;
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_ctl);
        GetIpfixFlushTimerCtl(A, profileIdBitmap_f, &flush_tim_ctl, p_bulk_op->prof_id_bmp);
        if (GetIpfixFlushTimerCtl(V, operationBasedOnProfileIdMatch_f, &flush_tim_ctl))
        {
            CTC_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_BY_PROF);
        }
        if ((0 == GetIpfixFlushTimerCtl(V, flushOpIgnorDmaStatus_f, &flush_tim_ctl)) && (0 == GetIpfixFlushTimerCtl(V, flushOpDoNotTellDma_f, &flush_tim_ctl)))
        {
            CTC_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_DUMP_EN);
        }
        if (GetIpfixFlushTimerCtl(V, flushFlowDeleteKeyMode_f, &flush_tim_ctl) && GetIpfixFlushTimerCtl(V, flushFlowUpdateAdMode_f, &flush_tim_ctl))
        {
            CTC_BIT_SET(p_bulk_op->flag, CTC_IPFIX_OP_FLAG_FLUSH_EN);
        }
        tbl_id = (p_bulk_op->p_param->dir == CTC_INGRESS)? IpfixFlushTimerUpdateCtl0_t : IpfixFlushTimerUpdateCtl1_t;
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_up_ctl);
        if(GetIpfixFlushTimerUpdateCtl(V, dmaIsFull_f, &flush_tim_up_ctl))
        {
            p_bulk_op->p_param->start_index = GetIpfixFlushTimerUpdateCtl(V, curScanPtr_f, &flush_tim_up_ctl);
        }
        else
        {
            p_bulk_op->p_param->start_index = 0;
        }
        break;
    case CTC_IPFIX_PROP_BULK_MISS:
        p_bulk_op_miss = (ctc_ipfix_bulk_op_miss_t*)p_ipfix_prop->value;
        tbl_id = (p_bulk_op_miss->dir == CTC_INGRESS)? IpfixFlushTimerUpdateCtl0_t : IpfixFlushTimerUpdateCtl1_t;
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &flush_tim_up_ctl);
        p_bulk_op_miss->one_round_done = !GetIpfixFlushTimerUpdateCtl(V, updEn_f, &flush_tim_up_ctl);
        
        tbl_id = (p_bulk_op_miss->dir == CTC_INGRESS)? IpfixFlushMissDmaFifoFullCount0_t : IpfixFlushMissDmaFifoFullCount1_t;
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &dump_miss_cnt);
        p_bulk_op_miss->miss_cnt = GetIpfixFlushMissDmaFifoFullCount(V, count1_f, &dump_miss_cnt);
        break;
    case CTC_IPFIX_PROP_MBURST:
        /*MMU config*/
        cmd = DRV_IOR( IpfixEngineMmuCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mmu_ctl));
        pro_mburst->mburst_on_thrd = GetIpfixEngineMmuCtl(V, maxQueCntExportThrd_f, &mmu_ctl);
        pro_mburst->mburst_off_thrd = GetIpfixEngineMmuCtl(V, minQueCntExportThrd_f, &mmu_ctl);
        pro_mburst->mburst_cnt_thrd = GetIpfixEngineMmuCtl(V, maxMbInstantThrd_f, &mmu_ctl);
        break;
    case CTC_IPFIX_PROP_HASH_CONFLICT_THRD :
        cmd = DRV_IOR(IpfixEngineCtl0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ctl0));
        *((uint32*)p_ipfix_prop->value) = GetIpfixEngineCtl0(V, hashConflictThrd_f , &ipfix_ctl0);
        break;
    case CTC_IPFIX_PROP_LOW_LATENCY :
        cmd = DRV_IOR(IpeFwdFlowHashCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipe_fwd_flow_ctl));
        *((uint32*)p_ipfix_prop->value) = GetIpeFwdFlowHashCtl(V, bypassIpfixResult_f, &ipe_fwd_flow_ctl);
        break;
    default:
        break;
    }

    return CTC_E_NONE;
}


int32
sys_at_ipfix_get_flow_cfg(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint32 cmd = 0;
    uint32  samping_idx = 0;
    uint8 bypass_bmp =0;
    uint8 bypass_bmp_discard =0;
    uint8 bypass_bmp_burst =0;
    uint8 bypass_bmp_latency =0;
    uint8 step = 0;
    uint32  cfg_table_id;
    uint32  sample_cfg_table_id;
    IpfixIngSamplingProfile_m  ipfix_ing_sampleing_cfg;
    DsIngressIpfixConfig_m  ipfix_cfg;
    uint32 sys_deny_reason_bmp = 0;
    uint32 sys_suppress_reason_bmp = 0;
    uint32 hw_drop_report_bmp[2] = {0};
    ds_t ds;
    uint8 alu_en = 0;

    uint8 i =0;
    uint32 alu_profile_tbl_idx=0;
    uint32 alu_profile_id=0;
    uint32 alu_table_pos_egs[8] = {DsIpfixAluProfile01_t, DsIpfixAluProfile11_t, DsIpfixAluProfile21_t, DsIpfixAluProfile31_t,
                              DsIpfixAlu16Profile01_t, DsIpfixAlu16Profile11_t, DsIpfixAlu16Profile21_t, DsIpfixAlu16Profile31_t};
    sys_ipfix_xalu_vec_t* xalu_old_vec;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    step = IpfixSamplingProfile0_array_1_samplingPktInterval_f - IpfixSamplingProfile0_array_0_samplingPktInterval_f;
    sample_cfg_table_id = (p_flow_cfg->dir == CTC_INGRESS) ? IpfixSamplingProfile0_t : IpfixSamplingProfile1_t;
    cfg_table_id = (p_flow_cfg->dir == CTC_INGRESS) ? DsIpfixConfig0_t : DsIpfixConfig1_t;
    cmd = DRV_IOR( sample_cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_ing_sampleing_cfg));
    cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg));

    alu_en =  GetDsIpfixConfig(V, aluEn_f, &ipfix_cfg);
    if (alu_en)
    {
        xalu_old_vec = ctc_vector_get(p_usw_ipfix_master[lchip]->xalu_vec, p_flow_cfg->profile_id);/*just storage valid*/
        if (!xalu_old_vec)
        {
            CTC_ERROR_RETURN(CTC_E_NOT_EXIST);
        }
        while(alu_en)
        {
            if(alu_en & 0x1)
            {
                alu_profile_id = GetDsIpfixConfig(V, g_0_aluProfileId_f + alu_profile_tbl_idx, &ipfix_cfg);
                cmd = DRV_IOR( alu_table_pos_egs[alu_profile_tbl_idx], DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, alu_profile_id, DRV_CMD_PP_EN(cmd), &ds));

                p_flow_cfg->track[i].count_mode = (xalu_old_vec->xalu_type[alu_profile_tbl_idx] >> 7);
                p_flow_cfg->track[i].type = xalu_old_vec->xalu_type[alu_profile_tbl_idx] & 0x7f;
                p_flow_cfg->track[i].valid = 1;

                p_flow_cfg->track[i].count_thrd = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?GetDsIpfixAluProfile(V, arg0_f, &ds)
                                                                                    :GetDsIpfixAlu16Profile(V, arg0_f, &ds);
                i++;
            }
            alu_profile_tbl_idx++;
            alu_en = alu_en>>1;
        }
    }

    p_flow_cfg->tcp_end_detect_disable = GetDsIngressIpfixConfig(V, tcpSessionEndDetectDisable_f, &ipfix_cfg);
    p_flow_cfg->learn_disable = GetDsIngressIpfixConfig(V, sessionNumLimitEn_f, &ipfix_cfg);
    p_flow_cfg->log_pkt_count = GetDsIngressIpfixConfig(V, ipfixMirrorCount_f, &ipfix_cfg);

    bypass_bmp = GetDsIngressIpfixConfig(V, flowBypassIpfixBmp_f, &ipfix_cfg);
    CTC_BIT_SET(bypass_bmp_discard, 1);
    CTC_BIT_SET(bypass_bmp_discard, 3);
    CTC_BIT_SET(bypass_bmp_discard, 5);
    CTC_BIT_SET(bypass_bmp_discard, 7);
    if (bypass_bmp == (bypass_bmp & (~bypass_bmp_discard)))
    {
        CTC_SET_FLAG(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET);
    }
    else if (bypass_bmp == (bypass_bmp & bypass_bmp_discard))
    {
        CTC_SET_FLAG(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET);
    }
    CTC_BIT_SET(bypass_bmp_burst, 2);
    CTC_BIT_SET(bypass_bmp_burst, 3);
    CTC_BIT_SET(bypass_bmp_burst, 6);
    CTC_BIT_SET(bypass_bmp_burst, 7);
    if (bypass_bmp == (bypass_bmp & (~bypass_bmp_burst)))
    {
        CTC_SET_FLAG(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_BURST);
    }
    else if (bypass_bmp == (bypass_bmp & bypass_bmp_burst))
    {
        CTC_SET_FLAG(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_BURST);
    }
    CTC_BIT_SET(bypass_bmp_latency, 4);
    CTC_BIT_SET(bypass_bmp_latency, 5);
    CTC_BIT_SET(bypass_bmp_latency, 6);
    CTC_BIT_SET(bypass_bmp_latency, 7);
    if (bypass_bmp == (bypass_bmp & (~bypass_bmp_latency)))
    {
        CTC_SET_FLAG(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_LATENCY);
    }
    else if (bypass_bmp == (bypass_bmp & bypass_bmp_latency))
    {
        CTC_SET_FLAG(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_LATENCY);
    }
    if(bypass_bmp == 0)
    {
        p_flow_cfg->flow_type = CTC_IPFIX_FLOW_TYPE_ALL_PACKET;
    }
    if(GetDsIpfixConfig0(V, samplingEn_f, &ipfix_cfg))
    {
        samping_idx = GetDsIpfixConfig0(V, samplingProfileIndex_f, &ipfix_cfg);
        p_flow_cfg->sample_mode = GetIpfixSamplingProfile(V, array_0_samplingMode_f + samping_idx*step, &ipfix_ing_sampleing_cfg);
        p_flow_cfg->sample_type = GetIpfixSamplingProfile(V, array_0_countBasedSamplingMode_f+samping_idx*step, &ipfix_ing_sampleing_cfg);

        if(p_flow_cfg->dir == CTC_INGRESS)
        {
            p_flow_cfg->sample_interval = p_usw_ipfix_master[lchip]->sip_interval[samping_idx];
        }
        else
        {
            p_flow_cfg->sample_interval = p_usw_ipfix_master[lchip]->sip_interval[samping_idx+MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)];
        }
    }
    sys_suppress_reason_bmp = GetDsIpfixConfig0(V, disableCaptureEvent_f, &ipfix_cfg);
    sys_deny_reason_bmp = GetDsIpfixConfig0(V, denySendDmaBitMap_f, &ipfix_cfg);
    _sys_usw_ipfix_map_reason_sys_to_ctc_bmp(lchip, sys_suppress_reason_bmp, sys_deny_reason_bmp, p_flow_cfg);
    GetDsIpfixConfig(A, discardVectorExportBmp_f, &ipfix_cfg, hw_drop_report_bmp);
    CTC_BMP_UNSET(hw_drop_report_bmp, CTC_DROP_MAX);
    sal_memcpy(p_flow_cfg->drop_report_bmp, hw_drop_report_bmp, sizeof(hw_drop_report_bmp));
    p_flow_cfg->drop_pkt_mode = !GetDsIpfixConfig1(V, recordDiscardVectorEn_f, &ipfix_cfg);
    return CTC_E_NONE;
}
int32
_sys_at_ipfix_flow_track(uint8 lchip, void* ds1, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint32 cmd = 0;
    int32 ret = CTC_E_NONE;
    DsIpfixAluProfile_m ds;
    DsIpfixAluProfile_m tmp_ds[CTC_IPFIX_FLOW_TRACK_MAX];
    uint32 loop_i= 0;
    DsIpfixConfig1_m* ipfix_cfg = (DsIpfixConfig1_m*)ds1;
    uint32 i = 0;
    uint8 alu_en = 0;
    uint8 old_alu_en = 0;
    uint8 aluExportClear_en = 0;
    struct alu_profile alu_profile_type;
    uint32 alu_table_pos_egs[8] = {DsIpfixAluProfile01_t, DsIpfixAluProfile11_t, DsIpfixAluProfile21_t, DsIpfixAluProfile31_t,
                              DsIpfixAlu16Profile01_t, DsIpfixAlu16Profile11_t, DsIpfixAlu16Profile21_t, DsIpfixAlu16Profile31_t};
    sys_ipfix_xalu_profile_t* p_get_xalu_profile = NULL;
    sys_ipfix_xalu_profile_t new_xalu_profile;
    sys_ipfix_xalu_profile_t old_xalu_profile;
    uint8 alu_profile_tbl_idx = 0;/*alu profile table number*/
    uint8 alu_profile_id = 0;/*cfg table storage alu profile id*/
    uint8 mode_32_num=0;
    uint8 mode_16_num=0;
    uint16 width_pos_record[2][CTC_IPFIX_FLOW_TRACK_MAX];
    sys_ipfix_xalu_vec_t* xalu_new_vec = NULL;
    sys_ipfix_xalu_vec_t* p_xalu_vec= NULL;
    ctc_ipfix_flow_track_t tmp_track[CTC_IPFIX_FLOW_TRACK_MAX];

    sal_memset(&new_xalu_profile, 0, sizeof(new_xalu_profile));
    sal_memset(&old_xalu_profile, 0, sizeof(old_xalu_profile));
    sal_memset(tmp_track, 0, sizeof(tmp_track));
    sal_memset(&ds, 0, sizeof(ds));
    sal_memset(width_pos_record, 0, sizeof(width_pos_record));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    /*1.egress check and ad resorce check*/
    for (loop_i = 0; loop_i < CTC_IPFIX_FLOW_TRACK_MAX; loop_i++)
    {
        if (p_flow_cfg->track[loop_i].count_mode && p_flow_cfg->track[loop_i].valid)/*32bit width valid*/
        {
            width_pos_record[0][mode_32_num] = loop_i;/*32bit width valid index*/
            mode_32_num++;
        }
        else if (p_flow_cfg->track[loop_i].valid)/*16bit width valid*/
        {
            width_pos_record[1][mode_16_num] = loop_i;/*16bit width valid index*/
            mode_16_num++;
        }
        if (p_flow_cfg->track[loop_i].valid &&
            (((p_flow_cfg->track[loop_i].type == CTC_IPFIX_FLOW_TRACK_BURST_EVENT || p_flow_cfg->track[loop_i].type == CTC_IPFIX_FLOW_TRACK_LATENCY_EVENT)
            && !p_flow_cfg->track[loop_i].count_thrd )|| (p_flow_cfg->track[loop_i].count_mode == 0 && p_flow_cfg->track[loop_i].count_thrd > 0xFFFF)))
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    if (mode_32_num*2 + mode_16_num > AD_16BIT_RESOURCE)/*ad resorce check*/
    {
        return CTC_E_NO_RESOURCE;
    }

    if (p_flow_cfg->dir == CTC_INGRESS && (mode_32_num + mode_16_num))/*egress check*/
    {
        return CTC_E_INVALID_PARAM;
    }

    /*2.spool remove*/
    old_alu_en =  GetDsIpfixConfig(V, aluEn_f, ipfix_cfg);
    if (old_alu_en)
    {
        while(old_alu_en)
        {
            if(old_alu_en & 0x1)
            {
                alu_profile_id = GetDsIpfixConfig(V, g_0_aluProfileId_f + alu_profile_tbl_idx, ipfix_cfg);
                cmd = DRV_IOR( alu_table_pos_egs[alu_profile_tbl_idx], DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, alu_profile_id, DRV_CMD_PP_EN(cmd), &ds));
                sal_memcpy(&old_xalu_profile.ds, &ds, sizeof(DsIpfixAluProfile_m));
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "remove alu spool profile id = %d\n", alu_profile_id);
                ret = ctc_spool_remove(p_usw_ipfix_master[lchip]->xalu_spool, &old_xalu_profile, NULL);
                if (ret)
                {
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "remove alu profile spool error, %%ret=%d\n", ret);
                    return ret;
                }
            }
            old_alu_en = old_alu_en>>1;
            alu_profile_tbl_idx++;
        }
        p_xalu_vec = ctc_vector_get(p_usw_ipfix_master[lchip]->xalu_vec, p_flow_cfg->profile_id);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XALU_VEC, 1);
        ctc_vector_del(p_usw_ipfix_master[lchip]->xalu_vec, p_flow_cfg->profile_id);
        mem_free(p_xalu_vec);
        old_alu_en = 0;
        SetDsIpfixConfig(V, aluEn_f, ipfix_cfg, 0);
        SetDsIpfixConfig(V, aluExportClear_f, ipfix_cfg, 0); /* compatible for ALU clear*/
    }
    /*3.add alu trace profile*/
    if(mode_32_num + mode_16_num)
    {
        MALLOC_ZERO(MEM_IPFIX_MODULE, xalu_new_vec, sizeof(sys_ipfix_xalu_vec_t));
    }
    for (loop_i = 0; loop_i < mode_32_num + mode_16_num; loop_i++)  /* valid xalu loop*/
    {
        if (loop_i < mode_32_num)
        {
            i = width_pos_record[0][loop_i];
            alu_profile_tbl_idx = loop_i;
        }
        else if (loop_i < mode_32_num + mode_16_num)
        {
            i = width_pos_record[1][loop_i-mode_32_num];
            alu_profile_tbl_idx = (alu_profile_tbl_idx<(SYS_ALU_USE_32BITWISE-1))?loop_i:(loop_i + mode_32_num);
        }
        sal_memset(&alu_profile_type, 0, sizeof(alu_profile_type));
        switch (p_flow_cfg->track[i].type)
        {
            case CTC_IPFIX_FLOW_TRACK_BURST_EVENT : /*MOB*/
                alu_profile_type.cmp0MaskL = 0;
                alu_profile_type.cmp1SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?6:14;/*get arg0 data*/
                alu_profile_type.cmp1MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.cmp1LUseRd = 1;
                alu_profile_type.condOp = SYS_ALU_BITWISE_ST0_CONDOP;
                alu_profile_type.dataOp = SYS_ALU_DATA_AUTO_INCREMENT;
                alu_profile_type.dataOp1 = SYS_ALU_DATA_AUTO_INCREMENT;
                alu_profile_type.cmp0Op1 = SYS_ALU_CMP_LESS;
                alu_profile_type.cmp0Op = SYS_ALU_CMP_LESS;
                alu_profile_type.cmp1Op1 = SYS_ALU_CMP_GREATER_OR_EQUAL;
                alu_profile_type.cmp1Op = SYS_ALU_CMP_GREATER_OR_EQUAL;
                alu_profile_type.exportEn = SYS_ALU_EXPORT_BMP;
                alu_profile_type.typeSel = ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) / BIT_WIDTH_16);/*get discard XPI data*/
                alu_profile_type.typeMask = (0x1 << ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) % BIT_WIDTH_16));
                alu_profile_type.typeValue = 0;
                alu_profile_type.arg0 = p_flow_cfg->track[i].count_thrd;
                alu_profile_type.cmp0SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?(SYS_IPFIX_XBUS_RSV_MICRO_BURST*4 / BIT_WIDTH_32)
                                                                                         :(SYS_IPFIX_XBUS_RSV_MICRO_BURST*4 / BIT_WIDTH_32)*2;/*used dword 3*/
                alu_profile_type.cmp0MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?(0x1 << (SYS_IPFIX_XBUS_RSV_MICRO_BURST*4 % BIT_WIDTH_32))
                                                                             :((0x1 << (SYS_IPFIX_XBUS_RSV_MICRO_BURST*4 % BIT_WIDTH_32))-16);/*used  dword 3 bit 16*/
                alu_profile_type.exportReason = SYS_IPFIX_EXPORTREASON_BUFFER_DROP_OVERFLOW;
                alu_profile_type.useAsAlu16 = !p_flow_cfg->track[i].count_mode;/*Alu16 or Alu32*/
                break;
            case CTC_IPFIX_FLOW_TRACK_LATENCY_EVENT : /*MOL*/
                alu_profile_type.cmp0MaskL = 0;
                alu_profile_type.cmp1SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?6:14;/*get arg0 data*/
                alu_profile_type.cmp1MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.cmp1LUseRd = 1;
                alu_profile_type.condOp = SYS_ALU_BITWISE_ST0_CONDOP;
                alu_profile_type.dataOp = SYS_ALU_DATA_AUTO_INCREMENT;
                alu_profile_type.dataOp1 = SYS_ALU_DATA_AUTO_INCREMENT;
                alu_profile_type.cmp0Op1 = SYS_ALU_CMP_LESS;
                alu_profile_type.cmp0Op = SYS_ALU_CMP_LESS;
                alu_profile_type.cmp1Op1 = SYS_ALU_CMP_GREATER_OR_EQUAL;
                alu_profile_type.cmp1Op = SYS_ALU_CMP_GREATER_OR_EQUAL;
                alu_profile_type.exportEn = SYS_ALU_EXPORT_BMP;
                alu_profile_type.typeSel = ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) / BIT_WIDTH_16);/*get discard XPI data*/
                alu_profile_type.typeMask = (0x1 << ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) % BIT_WIDTH_16));
                alu_profile_type.typeValue = 0;
                alu_profile_type.arg0 = p_flow_cfg->track[i].count_thrd;
                alu_profile_type.cmp0SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?(SYS_IPFIX_XBUS_RSV_LANTENCY_CONGEST*4 / BIT_WIDTH_32)
                    :(SYS_IPFIX_XBUS_RSV_LANTENCY_CONGEST*4 / BIT_WIDTH_32)*2;/*used word 3*/
                alu_profile_type.cmp0MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?(0x1 << ((SYS_IPFIX_XBUS_RSV_LANTENCY_CONGEST*4 + 1) % BIT_WIDTH_32))
                    :((0x1 << ((SYS_IPFIX_XBUS_RSV_LANTENCY_CONGEST*4 + 1) % BIT_WIDTH_32))-16);/*used word 3 bit 17*/
                alu_profile_type.exportReason = SYS_IPFIX_EXPORTREASON_LATENCY_DROP_OVERFLOW;
                alu_profile_type.useAsAlu16 = !p_flow_cfg->track[i].count_mode;/*Alu16 or Alu32*/
                break;
            case CTC_IPFIX_FLOW_TRACK_MAX_LATENCY :
                alu_profile_type.cmp0MaskL = 0;
                alu_profile_type.condOp = SYS_ALU_BITWISE_ST0_CONDOP;
                alu_profile_type.dataOp = SYS_ALU_DATA_CALCULATE_MAX;/*update session*/
                alu_profile_type.dataOp1 = SYS_ALU_DATA_CALCULATE_EQUAL;/*add session*/
                alu_profile_type.cmp0Op1 = SYS_ALU_CMP_LESS;/*add session*/
                alu_profile_type.cmp0Op = SYS_ALU_CMP_TRUE ;/*update session*/
                alu_profile_type.typeSel = ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) / BIT_WIDTH_16);/*get discard XPI data*/
                alu_profile_type.typeMask = 0x1 << ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) % BIT_WIDTH_16);
                alu_profile_type.typeValue = 0;
                alu_profile_type.dataSelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?4:8;/*used dword 4*/
                alu_profile_type.dataMaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.cmp0SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?4:8;/*used dword 4*/
                alu_profile_type.cmp0MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.useAsAlu16 = !p_flow_cfg->track[i].count_mode;/*Alu16 or Alu32*/
                break;
            case CTC_IPFIX_FLOW_TRACK_MIN_LATENCY :
                alu_profile_type.cmp0MaskL = 0;
                alu_profile_type.condOp = SYS_ALU_BITWISE_ST0_CONDOP;
                alu_profile_type.dataOp = SYS_ALU_DATA_CALCULATE_MIN;/*update session*/
                alu_profile_type.dataOp1 = SYS_ALU_DATA_CALCULATE_EQUAL;/*add session*/
                alu_profile_type.cmp0Op1 = SYS_ALU_CMP_LESS;/*add session*/
                alu_profile_type.cmp0Op = SYS_ALU_CMP_TRUE ;/*update session*/
                alu_profile_type.typeSel = ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) / BIT_WIDTH_16);/*get discard XPI data*/
                alu_profile_type.typeMask = 0x1 << ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) % BIT_WIDTH_16);
                alu_profile_type.typeValue = 0;
                alu_profile_type.dataSelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?4:8;/*used dword 4*/
                alu_profile_type.dataMaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.cmp0SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?4:8;/*used dword 4*/
                alu_profile_type.cmp0MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.useAsAlu16 = !p_flow_cfg->track[i].count_mode;/*Alu16 or Alu32*/
                break;
            case CTC_IPFIX_FLOW_TRACK_AVG_LATENCY:
                alu_profile_type.cmp0MaskL = 0;
                alu_profile_type.condOp = SYS_ALU_BITWISE_ST0_CONDOP;
                alu_profile_type.dataOp = SYS_ALU_DATA_CALCULATE_AVERAGE;/*update session*/
                alu_profile_type.dataOp1 = SYS_ALU_DATA_CALCULATE_EQUAL;/*add session*/
                alu_profile_type.cmp0Op1 = SYS_ALU_CMP_LESS;/*add session*/
                alu_profile_type.cmp0Op = SYS_ALU_CMP_TRUE ;/*update session*/
                alu_profile_type.typeSel = ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) / BIT_WIDTH_16);/*get discard XPI data*/
                alu_profile_type.typeMask = 0x1 << ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) % BIT_WIDTH_16);
                alu_profile_type.typeValue = 0;
                alu_profile_type.weight = 2;
                alu_profile_type.dataSelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?4:8;/*used dword 4*/
                alu_profile_type.dataMaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.cmp0SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?4:8;/*used dword 4*/
                alu_profile_type.cmp0MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0xFFFFFFFF:0xFFFF;
                alu_profile_type.useAsAlu16 = !p_flow_cfg->track[i].count_mode;/*Alu16 or Alu32*/
                break;
            case CTC_IPFIX_FLOW_TRACK_TS:
                alu_profile_type.cmp0MaskL = 0;
                alu_profile_type.condOp = SYS_ALU_BITWISE_ST0_CONDOP;
                alu_profile_type.dataOp = SYS_ALU_DATA_CALCULATE_EQUAL;/*update session*/
                alu_profile_type.dataOp1 = SYS_ALU_DATA_CALCULATE_EQUAL;/*add session*/
                alu_profile_type.cmp0Op1 = SYS_ALU_CMP_TRUE;/*add session*/
                alu_profile_type.cmp0Op = SYS_ALU_CMP_TRUE ;/*update session*/
                alu_profile_type.typeSel = ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) / BIT_WIDTH_16);/*get discard XPI data*/
                alu_profile_type.typeMask = 0x1 << ((SYS_IPFIX_XBUS_RSV_DISCARD*4 + 2) % BIT_WIDTH_16);
                alu_profile_type.typeValue = 0;
                alu_profile_type.dataSelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?5:10;/*used dword 5*/
                alu_profile_type.dataMaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0x3FFFFF:0xFFFF;
                alu_profile_type.cmp0SelR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?5:10;/*used dword 5*/
                alu_profile_type.cmp0MaskR = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?0x3FFFFF:0xFFFF;
                alu_profile_type.useAsAlu16 = !p_flow_cfg->track[i].count_mode;/*Alu16 or Alu32*/
                break;
            default:
                break;
        }

        if (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)
        {
            SetDsIpfixAluProfile(V, logEn_f, &ds, alu_profile_type.logEn);
            SetDsIpfixAluProfile(V, discardEn_f, &ds, alu_profile_type.discardEn);
            SetDsIpfixAluProfile(V, aluEn_f, &ds, alu_profile_type.aluEn);
            SetDsIpfixAluProfile(V, cmp0LUseRd_f, &ds, alu_profile_type.cmp0LUseRd);
            SetDsIpfixAluProfile(V, cmp0SelL_f, &ds, alu_profile_type.cmp0SelL);
            SetDsIpfixAluProfile(V, cmp1SelL_f, &ds, alu_profile_type.cmp1SelL);
            SetDsIpfixAluProfile(V, arg1_f, &ds, alu_profile_type.arg1);
            SetDsIpfixAluProfile(V, cmp1MaskL_f, &ds, alu_profile_type.cmp1MaskL);

            SetDsIpfixAluProfile(V, cmp0MaskL_f, &ds, alu_profile_type.cmp0MaskL);
            SetDsIpfixAluProfile(V, cmp1SelR_f, &ds, alu_profile_type.cmp1SelR);
            SetDsIpfixAluProfile(V, cmp1MaskR_f, &ds, alu_profile_type.cmp1MaskR);
            SetDsIpfixAluProfile(V, cmp1LUseRd_f, &ds, alu_profile_type.cmp1LUseRd);
            SetDsIpfixAluProfile(V, condOp_f, &ds, alu_profile_type.condOp);
            SetDsIpfixAluProfile(V, dataOp_f, &ds, alu_profile_type.dataOp);
            SetDsIpfixAluProfile(V, dataOp1_f, &ds, alu_profile_type.dataOp1);
            SetDsIpfixAluProfile(V, cmp0Op1_f, &ds, alu_profile_type.cmp0Op1);
            SetDsIpfixAluProfile(V, cmp0Op_f, &ds, alu_profile_type.cmp0Op);
            SetDsIpfixAluProfile(V, cmp1Op1_f, &ds, alu_profile_type.cmp1Op1);
            SetDsIpfixAluProfile(V, cmp1Op_f, &ds, alu_profile_type.cmp1Op);
            SetDsIpfixAluProfile(V, exportEn_f, &ds, alu_profile_type.exportEn);
            SetDsIpfixAluProfile(V, typeSel_f, &ds, alu_profile_type.typeSel);
            SetDsIpfixAluProfile(V, typeMask_f, &ds, alu_profile_type.typeMask);
            SetDsIpfixAluProfile(V, typeValue_f, &ds, alu_profile_type.typeValue);
            SetDsIpfixAluProfile(V, dataSelR_f, &ds, alu_profile_type.dataSelR);
            SetDsIpfixAluProfile(V, dataMaskR_f, &ds, alu_profile_type.dataMaskR);
            SetDsIpfixAluProfile(V, weight_f, &ds, alu_profile_type.weight);
            SetDsIpfixAluProfile(V, arg0_f, &ds, alu_profile_type.arg0);
            SetDsIpfixAluProfile(V, cmp0SelR_f, &ds, alu_profile_type.cmp0SelR);
            SetDsIpfixAluProfile(V, cmp0MaskR_f, &ds, alu_profile_type.cmp0MaskR);
            SetDsIpfixAluProfile(V, exportReason_f, &ds, alu_profile_type.exportReason);
            SetDsIpfixAluProfile(V, useAsAlu16_f, &ds, alu_profile_type.useAsAlu16);
        }
        else
        {
            SetDsIpfixAlu16Profile(V, logEn_f, &ds, alu_profile_type.logEn);
            SetDsIpfixAlu16Profile(V, discardEn_f, &ds, alu_profile_type.discardEn);
            SetDsIpfixAlu16Profile(V, aluEn_f, &ds, alu_profile_type.aluEn);
            SetDsIpfixAlu16Profile(V, cmp0LUseRd_f, &ds, alu_profile_type.cmp0LUseRd);
            SetDsIpfixAlu16Profile(V, cmp0SelL_f, &ds, alu_profile_type.cmp0SelL);
            SetDsIpfixAlu16Profile(V, cmp1SelL_f, &ds, alu_profile_type.cmp1SelL);
            SetDsIpfixAlu16Profile(V, arg1_f, &ds, alu_profile_type.arg1);
            SetDsIpfixAlu16Profile(V, cmp1MaskL_f, &ds, alu_profile_type.cmp1MaskL);

            SetDsIpfixAlu16Profile(V, cmp0MaskL_f, &ds, alu_profile_type.cmp0MaskL);
            SetDsIpfixAlu16Profile(V, cmp1SelR_f, &ds, alu_profile_type.cmp1SelR);
            SetDsIpfixAlu16Profile(V, cmp1MaskR_f, &ds, alu_profile_type.cmp1MaskR);
            SetDsIpfixAlu16Profile(V, cmp1LUseRd_f, &ds, alu_profile_type.cmp1LUseRd);
            SetDsIpfixAlu16Profile(V, condOp_f, &ds, alu_profile_type.condOp);
            SetDsIpfixAlu16Profile(V, dataOp_f, &ds, alu_profile_type.dataOp);
            SetDsIpfixAlu16Profile(V, dataOp1_f, &ds, alu_profile_type.dataOp1);
            SetDsIpfixAlu16Profile(V, cmp0Op1_f, &ds, alu_profile_type.cmp0Op1);
            SetDsIpfixAlu16Profile(V, cmp0Op_f, &ds, alu_profile_type.cmp0Op);
            SetDsIpfixAlu16Profile(V, cmp1Op1_f, &ds, alu_profile_type.cmp1Op1);
            SetDsIpfixAlu16Profile(V, cmp1Op_f, &ds, alu_profile_type.cmp1Op);
            SetDsIpfixAlu16Profile(V, exportEn_f, &ds, alu_profile_type.exportEn);
            SetDsIpfixAlu16Profile(V, typeSel_f, &ds, alu_profile_type.typeSel);
            SetDsIpfixAlu16Profile(V, typeMask_f, &ds, alu_profile_type.typeMask);
            SetDsIpfixAlu16Profile(V, typeValue_f, &ds, alu_profile_type.typeValue);
            SetDsIpfixAlu16Profile(V, dataSelR_f, &ds, alu_profile_type.dataSelR);
            SetDsIpfixAlu16Profile(V, dataMaskR_f, &ds, alu_profile_type.dataMaskR);
            SetDsIpfixAlu16Profile(V, weight_f, &ds, alu_profile_type.weight);
            SetDsIpfixAlu16Profile(V, arg0_f, &ds, alu_profile_type.arg0);
            SetDsIpfixAlu16Profile(V, cmp0SelR_f, &ds, alu_profile_type.cmp0SelR);
            SetDsIpfixAlu16Profile(V, cmp0MaskR_f, &ds, alu_profile_type.cmp0MaskR);
            SetDsIpfixAlu16Profile(V, exportReason_f, &ds, alu_profile_type.exportReason);
        }

        /*add spool*/
        sal_memcpy(&new_xalu_profile.ds, &ds, sizeof(DsIpfixAluProfile_m));
        ret = ctc_spool_add(p_usw_ipfix_master[lchip]->xalu_spool, &new_xalu_profile, NULL, &p_get_xalu_profile);
        if (ret)
        {
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "add xalu profile spool error, %%ret=%d\n", ret);
            goto error1;
        }
        sal_memcpy(&tmp_ds[loop_i], &ds, sizeof(DsIpfixAluProfile_m));/*for remove spool*/
        alu_profile_id = p_get_xalu_profile->index.index;
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "p_get_xalu_profile->index = %d\n", p_get_xalu_profile->index.index);

        /*add vector*/
        xalu_new_vec->xalu_type[alu_profile_tbl_idx] = p_flow_cfg->track[i].type;
        xalu_new_vec->xalu_type[alu_profile_tbl_idx] |= (p_flow_cfg->track[i].count_mode << 7);

        cmd = DRV_IOW( alu_table_pos_egs[alu_profile_tbl_idx], DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, alu_profile_id, DRV_CMD_PP_EN(cmd), &ds), ret, error1);
        CTC_BIT_SET(alu_en, alu_profile_tbl_idx);/*alu table choose*/
        if (p_flow_cfg->track[i].type == CTC_IPFIX_FLOW_TRACK_BURST_EVENT || p_flow_cfg->track[i].type == CTC_IPFIX_FLOW_TRACK_LATENCY_EVENT)
        {
            if (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)
            {
                CTC_BIT_SET(aluExportClear_en, (alu_profile_tbl_idx*SYS_ALU_TWICE_16BITWISE_RECORD));
                if (p_flow_cfg->track[i].count_mode)
                {
                    CTC_BIT_SET(aluExportClear_en, (alu_profile_tbl_idx*SYS_ALU_TWICE_16BITWISE_RECORD + 1));
                }
            }
            else
            {
                CTC_BIT_SET(aluExportClear_en, (SYS_ALU_TWICE_16BITWISE_RECORD*(alu_profile_tbl_idx % SYS_ALU_USE_32BITWISE) + 1));
            }
        }
        DRV_SET_FIELD_VALUE(lchip, DsIpfixConfig_t, (DsIpfixConfig_g_0_aluProfileId_f+alu_profile_tbl_idx), ipfix_cfg, alu_profile_id);
    }
    SetDsIpfixConfig(V, aluEn_f, ipfix_cfg, alu_en);
    SetDsIpfixConfig(V, aluExportClear_f, ipfix_cfg, aluExportClear_en); /* compatible for ALU clear*/
    /*4.add vector*/
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XALU_VEC, 1);
    if(mode_32_num + mode_16_num)
    {
        if (FALSE == ctc_vector_add(p_usw_ipfix_master[lchip]->xalu_vec, p_flow_cfg->profile_id, xalu_new_vec))
        {
            ret = CTC_E_NO_MEMORY;
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " IPFIX ALU insert fail\n");
            goto error1;
        }
    }
    return CTC_E_NONE;
error1:
    mem_free(xalu_new_vec);
    if (alu_en)
    {
        while (loop_i)
        {
            loop_i--;
            sal_memcpy(&new_xalu_profile.ds, &tmp_ds[loop_i], sizeof(DsIpfixAluProfile_m));
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "remove new alu profile id = %d\n", new_xalu_profile.index.index);
            ret = ctc_spool_remove(p_usw_ipfix_master[lchip]->xalu_spool, &new_xalu_profile, NULL);
        }
    }
    return ret;
}

int32
sys_at_ipfix_set_flow_cfg(uint8 lchip, ctc_ipfix_flow_cfg_t* p_flow_cfg)
{
    uint32  cmd = 0;
    uint32  sample_enable = 0;
    uint32  sample_profile_index = 0;
    uint8   dir = 0;
    uint8   loop_i = 0;
    uint32  step = 0;
    int32   ret;
    uint32 value_a = 0;
    uint32  cfg_table_id;
    uint32  sample_cfg_table_id;
    uint32 sys_suppress_reason_bmp = 0;
    uint32 sys_deny_export_reason_bmp = 0;
    DsIpfixConfig0_m  ipfix_cfg;
    IpfixSamplingProfile_m  ipfix_sampling_cfg;
    uint8 bypass_bmp = 0;
    uint8 bypass_bmp_discard = 0;
    uint8 bypass_bmp_burst = 0;
    uint8 bypass_bmp_latency = 0;

    sys_ipfix_sample_profile_t* p_get_sample_prf = NULL;
    sys_ipfix_sample_profile_t new_sample_prf;
    sys_ipfix_sample_profile_t old_sample_prf;
    sys_ipfix_sample_profile_t tmp_sample_prf;


    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if((CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET) && CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET)) ||
        (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_BURST) && CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_BURST)) ||
        (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_LATENCY) && CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_LATENCY)))
    {
        return CTC_E_INVALID_PARAM;
    }
    for(loop_i=0; loop_i<32; loop_i++)
    {
        if(CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, loop_i) || CTC_IS_BIT_SET(p_flow_cfg->deny_export_reason_bmp, loop_i))
        {
            CTC_ERROR_RETURN(_sys_at_ipfix_get_export_reason_dir(loop_i, &dir));
            if(((CTC_INGRESS == p_flow_cfg->dir) && (CTC_EGRESS == dir)) ||((CTC_EGRESS == p_flow_cfg->dir) && (CTC_INGRESS == dir)))
            {
                SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "export reason dir error, flow dir:%d, export reason dir:%d\n", p_flow_cfg->dir, dir);
                return CTC_E_INVALID_PARAM;
            }
        }
    }

    /* default record discard export bmp*/
    if (!p_flow_cfg->drop_report_bmp[0] && !p_flow_cfg->drop_report_bmp[1])
    {
        _sys_tmm_ipfix_get_drop_init_value(p_flow_cfg->dir, p_flow_cfg->drop_report_bmp);
    }
    if(p_flow_cfg->drop_report_bmp[0] ||p_flow_cfg->drop_report_bmp[1])
    {
        for(loop_i=0; loop_i<CTC_DROP_MAX; loop_i++)
        {
            if(CTC_BMP_ISSET(p_flow_cfg->drop_report_bmp, loop_i))
            {
                CTC_ERROR_RETURN(_sys_tmm_ipfix_get_drop_dir(loop_i, &dir));
                if(((CTC_INGRESS == p_flow_cfg->dir) && (CTC_EGRESS == dir)) ||((CTC_EGRESS == p_flow_cfg->dir) && (CTC_INGRESS == dir)))
                {
                    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "drop reason dir error, flow dir:%d, drop reason dir:%d\n", p_flow_cfg->dir, dir);
                    return CTC_E_INVALID_PARAM;
                }
            }
        }
    }

    /*Ignore drop reason, if set 1, indicates drop_pkt_mode drop reason bitmap useless*/
    if((0 == p_flow_cfg->drop_pkt_mode)&&p_usw_ipfix_master[lchip]->ignore_drop_reason)
    {
        return CTC_E_INVALID_PARAM;
    }
    sal_memset(&ipfix_cfg, 0, sizeof(ipfix_cfg));
    sal_memset(&ipfix_sampling_cfg, 0, sizeof(ipfix_sampling_cfg));
    sal_memset(&new_sample_prf, 0, sizeof(new_sample_prf));
    sal_memset(&old_sample_prf, 0, sizeof(old_sample_prf));
    sal_memset(&tmp_sample_prf, 0, sizeof(tmp_sample_prf));
    if(CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_REASON_TC_MARK) || CTC_IS_BIT_SET(p_flow_cfg->deny_export_reason_bmp, CTC_IPFIX_REASON_TC_MARK) ||
        CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_REASON_EXPIRED))
    {
         return CTC_E_INVALID_PARAM;
    }
    if(!CTC_IS_BIT_SET(p_flow_cfg->suppress_reason_bmp, CTC_IPFIX_REASON_TC_MARK))
    {
        /* ipfix droppkt reason, dscp:bit0,bit1 */
        value_a = 2;
        cmd = DRV_IOW( IpePreLookupCtl_t, IpePreLookupCtl_tosShiftMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &value_a));
    }
    CTC_ERROR_RETURN(_sys_usw_ipfix_map_reason_ctc_to_sys_bmp(lchip, p_flow_cfg, &sys_suppress_reason_bmp, &sys_deny_export_reason_bmp));
    sample_cfg_table_id = (p_flow_cfg->dir == CTC_INGRESS) ? IpfixSamplingProfile0_t : IpfixSamplingProfile1_t;
    cfg_table_id = (p_flow_cfg->dir == CTC_INGRESS) ? DsIpfixConfig0_t : DsIpfixConfig1_t;
    cmd = DRV_IOR( cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
    cmd = DRV_IOR( sample_cfg_table_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampling_cfg));

    value_a = 0xFF;
    SetDsIpfixConfig(V, aluExportClear_f, &ipfix_cfg, value_a); /* compatible for ALU clear*/

    sample_enable = GetDsIpfixConfig(V, samplingEn_f, &ipfix_cfg);
    sample_profile_index = GetDsIpfixConfig(V, samplingProfileIndex_f, &ipfix_cfg);
    step = IpfixSamplingProfile_array_1_samplingPktInterval_f - IpfixSamplingProfile_array_0_samplingPktInterval_f;

    if (sample_enable)
     {
         old_sample_prf.dir = p_flow_cfg->dir;
         old_sample_prf.mode = GetIpfixSamplingProfile(V, \
                 array_0_samplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg)
                 | GetIpfixSamplingProfile(V, \
                 array_0_countBasedSamplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg) << 1;
         old_sample_prf.interval =(p_flow_cfg->dir == CTC_INGRESS)? p_usw_ipfix_master[lchip]->sip_interval[sample_profile_index]: \
         p_usw_ipfix_master[lchip]->sip_interval[sample_profile_index+MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)];
         old_sample_prf.mode |= GetIpfixSamplingProfile(V, \
                                    array_0_countBasedSamplingMode_f+step*sample_profile_index, &ipfix_sampling_cfg) << 1;
     }
     if (p_flow_cfg->sample_interval != 0) /*add or update*/
     {
         uint16 drv_interval = 0;
         new_sample_prf.dir = p_flow_cfg->dir;
         new_sample_prf.interval = p_flow_cfg->sample_interval;
         new_sample_prf.mode = (!!p_flow_cfg->sample_type << 1) | (!!p_flow_cfg->sample_mode);

         ret = ctc_spool_add(p_usw_ipfix_master[lchip]->sample_spool, &new_sample_prf, &old_sample_prf, &p_get_sample_prf);
         if (ret)
         {
             SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "add sample spool error, %%ret=%d\n", ret);
             return ret;
         }
         if (p_flow_cfg->dir == CTC_INGRESS)
         {
             p_usw_ipfix_master[lchip]->sip_interval[p_get_sample_prf->ad_index] = p_flow_cfg->sample_interval;
         }
         else
         {
             p_usw_ipfix_master[lchip]->sip_interval[p_get_sample_prf->ad_index + MCHIP_CAP(SYS_CAP_IPFIX_MAX_SAMPLE_PROFILE)] = p_flow_cfg->sample_interval;
         }

         /*write hw*/
         sample_profile_index = p_get_sample_prf->ad_index;
         _sys_usw_ipfix_sample_interval_convert(lchip, p_get_sample_prf, &drv_interval);
         SetIpfixSamplingProfile(V, array_0_samplingPktInterval_f + step*sample_profile_index, &ipfix_sampling_cfg, drv_interval);
         SetIpfixSamplingProfile(V, array_0_samplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg, p_get_sample_prf->mode&0x01);
         SetIpfixSamplingProfile(V, array_0_countBasedSamplingMode_f + step*sample_profile_index, &ipfix_sampling_cfg, (p_get_sample_prf->mode >> 1)&0x01);

         SetDsIpfixConfig(V, samplingProfileIndex_f, &ipfix_cfg, p_get_sample_prf->ad_index);
         SetDsIpfixConfig(V, samplingEn_f, &ipfix_cfg, 1);
         sal_memcpy(&tmp_sample_prf, &new_sample_prf, sizeof(sys_ipfix_sample_profile_t)); /* for error rollback*/
     }
     else if(sample_enable)
     {
         ret = ctc_spool_remove(p_usw_ipfix_master[lchip]->sample_spool, &old_sample_prf, &p_get_sample_prf);
         if (ret)
         {
             SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "remove sample spool error, %%ret=%d\n", ret);
             return ret;
         }
         /*write hw*/
         SetDsIpfixConfig(V, samplingProfileIndex_f, &ipfix_cfg, 0);
         SetDsIpfixConfig(V, samplingEn_f, &ipfix_cfg, 0);
     }
    /*IPFIX aim to packet type*/
     if (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_DISCARD_PACKET))
     {
         CTC_BIT_SET(bypass_bmp_discard, 1);
         CTC_BIT_SET(bypass_bmp_discard, 3);
         CTC_BIT_SET(bypass_bmp_discard, 5);
         CTC_BIT_SET(bypass_bmp_discard, 7);
     }
     else if (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_DISCARD_PACKET))
     {
         CTC_BIT_SET(bypass_bmp_discard, 0);
         CTC_BIT_SET(bypass_bmp_discard, 2);
         CTC_BIT_SET(bypass_bmp_discard, 4);
         CTC_BIT_SET(bypass_bmp_discard, 6);
     }
     else
     {
        bypass_bmp_discard = 0xff;
     }
     if (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_BURST))
     {
         CTC_BIT_SET(bypass_bmp_burst, 2);
         CTC_BIT_SET(bypass_bmp_burst, 3);
         CTC_BIT_SET(bypass_bmp_burst, 6);
         CTC_BIT_SET(bypass_bmp_burst, 7);
     }
     else if (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_BURST))
     {
         CTC_BIT_SET(bypass_bmp_burst, 0);
         CTC_BIT_SET(bypass_bmp_burst, 1);
         CTC_BIT_SET(bypass_bmp_burst, 4);
         CTC_BIT_SET(bypass_bmp_burst, 5);
     }
     else
     {
        bypass_bmp_burst = 0xff;
     }
     if (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_NON_LATENCY))
     {
         CTC_BIT_SET(bypass_bmp_latency, 4);
         CTC_BIT_SET(bypass_bmp_latency, 5);
         CTC_BIT_SET(bypass_bmp_latency, 6);
         CTC_BIT_SET(bypass_bmp_latency, 7);
     }
     else if (CTC_FLAG_ISSET(p_flow_cfg->flow_type, CTC_IPFIX_FLOW_TYPE_LATENCY))
     {
         CTC_BIT_SET(bypass_bmp_latency, 0);
         CTC_BIT_SET(bypass_bmp_latency, 1);
         CTC_BIT_SET(bypass_bmp_latency, 2);
         CTC_BIT_SET(bypass_bmp_latency, 3);
     }
     else
     {
        bypass_bmp_latency = 0xff;
     }
     bypass_bmp = (bypass_bmp_discard & bypass_bmp_burst & bypass_bmp_latency);
     bypass_bmp = (bypass_bmp == 0xff)? 0 : bypass_bmp; 
     SetDsIpfixConfig(V, flowBypassIpfixBmp_f, &ipfix_cfg, bypass_bmp);

     SetDsIpfixConfig(V, sessionNumLimitEn_f, &ipfix_cfg, !!p_flow_cfg->learn_disable);
     SetDsIpfixConfig(V, tcpSessionEndDetectDisable_f, &ipfix_cfg, !!p_flow_cfg->tcp_end_detect_disable);
     if (p_flow_cfg->dir == CTC_INGRESS)
     {
         SetDsIpfixConfig(V, ipfixMirrorCount_f, &ipfix_cfg, p_flow_cfg->log_pkt_count);
     }
     else if ((p_flow_cfg->dir == CTC_EGRESS) && ( p_flow_cfg->log_pkt_count))
     {
         return CTC_E_INVALID_PARAM;
     }
     SetDsIpfixConfig(V, disableCaptureEvent_f, &ipfix_cfg, sys_suppress_reason_bmp);
     SetDsIpfixConfig(V, denySendDmaBitMap_f, &ipfix_cfg, sys_deny_export_reason_bmp);
     CTC_ERROR_GOTO( _sys_tmm_ipfix_set_flow_drop_classid(lchip, &ipfix_cfg, &ipfix_cfg, p_flow_cfg), ret, error_pro);
     SetDsIpfixConfig1(V, recordDiscardVectorEn_f, &ipfix_cfg, !p_flow_cfg->drop_pkt_mode);
     CTC_ERROR_GOTO(_sys_at_ipfix_flow_track(lchip, &ipfix_cfg, p_flow_cfg), ret, error_pro);
     cmd = DRV_IOW(cfg_table_id, DRV_ENTRY_FLAG);
     CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_flow_cfg->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
     cmd = DRV_IOW( sample_cfg_table_id, DRV_ENTRY_FLAG);
     CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &ipfix_sampling_cfg));

      return CTC_E_NONE;

error_pro:

    if(p_flow_cfg->sample_interval != 0)
    {
        ctc_spool_remove(p_usw_ipfix_master[lchip]->sample_spool, &tmp_sample_prf, &p_get_sample_prf);
    }
    else if(sample_enable)
    {
        CTC_ERROR_DUMP(ctc_spool_add(p_usw_ipfix_master[lchip]->sample_spool, &old_sample_prf, NULL, NULL));
    }
    return ret;
}

STATIC int32
_sys_at_ipfix_decode_l2_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_mac_field_sel_t *field_sel = &field_sel_tmp.u.mac;

    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };
    sys_at_ipfix_l2_hashkey_decode_t *pkey_d = (sys_at_ipfix_l2_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_data->hash_salt = pkey_d->ipfixHashSalt;
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->ether_type = pkey_d->etherType;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_MAC, &field_sel_tmp));

    p_data->cvlan = (pkey_d->cvlanId_0_9) | (pkey_d->cvlanId_10_11 << 10);
    p_data->cvlan_cfi = pkey_d->cvtagCfi;
    p_data->cvlan_prio = pkey_d->cvtagCos;
    if (pkey_d->cvlanIdValid)
    {
        p_data->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
    }
    p_data->svlan = (pkey_d->svlanId_0_2) | (pkey_d->svlanId_3_11 << 3);
    p_data->svlan_cfi = pkey_d->svtagCfi;
    p_data->svlan_prio = pkey_d->svtagCos;
    if (pkey_d->svlanIdValid)
    {
        p_data->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
    }

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }

    /* macda macsa dst_cid src_cid */
    mac_da[0]= pkey_d->macDa_0_29 | ((pkey_d->macDa_30_47&0x3)<<30);
    mac_da[1]= pkey_d->macDa_30_47>>2;
    mac_sa[0] = pkey_d->macSa_0_13 | ((pkey_d->macSa_14_45&0x3FFFF) << 14);
    mac_sa[1] = (pkey_d->macSa_14_45 >> 18) | (pkey_d->macSa_46_47 << 14);

    p_data->dst_cid = (pkey_d->destCategoryId_0_9) | (pkey_d->destCategoryId_10_15 << 10);
    if (pkey_d->destCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
    }
    p_data->src_cid = pkey_d->srcCategoryId;
    if (pkey_d->srcCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
    }

    SYS_USW_SET_USER_MAC(p_data->dst_mac, mac_da);
    SYS_USW_SET_USER_MAC(p_data->src_mac, mac_sa);
    p_data->fid = (pkey_d->vsiId_0_7) | (pkey_d->vsiId_8_14 << 8) ; /* TMM ...*/

    return CTC_E_NONE;
}

int32
_sys_at_ipfix_decode_ipv4_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv4_field_sel_t *field_sel = &field_sel_tmp.u.ipv4;
    uint8 share_field_mode=0;
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    sys_at_ipfix_ipv4_hashkey_decode_t *pkey_d = (sys_at_ipfix_ipv4_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_data->hash_salt = pkey_d->ipfixHashSalt;
    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV4, &field_sel_tmp));

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }

    p_l3_info->ipv4.dscp = pkey_d->dscp;
    p_l3_info->ipv4.ttl = pkey_d->ttl_0_2 | (pkey_d->ttl_3_7 << 3);
    p_l3_info->ipv4.ecn = pkey_d->ecn;
    p_data->dst_cid = pkey_d->destCategoryId_0_13 | (pkey_d->destCategoryId_14_15<<14);
    if (pkey_d->destCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
    }
    p_l3_info->ipv4.ipda = (pkey_d->ipDa_0_13) | (pkey_d->ipDa_14_31 << 14);
    p_l3_info->ipv4.ipda_masklen = field_sel->ip_da_mask;
    p_data->src_cid = pkey_d->srcCategoryId;
    if (pkey_d->srcCategoryIdClassfied)
    {
        p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
    }

    p_l3_info->ipv4.ipsa = pkey_d->ipSa_0_13 | (pkey_d->ipSa_14_19 << 14) |(pkey_d->ipSa_20_31 << 20);
    p_l3_info->ipv4.ipsa_masklen = field_sel->ip_sa_mask;

    p_l4_info->type.ip_protocol = pkey_d->layer3HeaderProtocol;

    if (field_sel->vxlan_vni)
    {
        p_l4_info->vni = pkey_d->uL4__0_13 | ((pkey_d->uL4__14_31&0x3FF)<<14);
    }
    else if(field_sel->gre_key || field_sel->nvgre_key)
    {
        p_l4_info->gre_key = pkey_d->uL4__0_13 | (pkey_d->uL4__14_31<<14);
    }
    else if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP ==  p_l4_info->type.ip_protocol) && (field_sel->icmp_code || field_sel->icmp_type))
    {
        p_l4_info->icmp.icmpcode = (pkey_d->uL4__14_31>>2)&0xff;
        p_l4_info->icmp.icmp_type = (pkey_d->uL4__14_31>>10)&0xff;
    }
    else if((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP ==  p_l4_info->type.ip_protocol) && field_sel->igmp_type)
    {
        p_l4_info->igmp.igmp_type = (pkey_d->uL4__14_31>>10)&0xff;
    }
    else if ((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP == p_l4_info->type.ip_protocol || SYS_L4_PROTOCOL_UDP == p_l4_info->type.ip_protocol )) && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
        p_l4_info->l4_port.dest_port = pkey_d->uL4__0_13 | (pkey_d->uL4__14_31&0x3)<<14;
        p_l4_info->l4_port.source_port = pkey_d->uL4__14_31>>2;
    }

    /*share field*/
    p_l3_info->ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(pkey_d->fragInfo);
    p_l4_info->tcp_flags = pkey_d->tcpFlags_0_6 | (pkey_d->tcpFlags_7_7 << 7);
    if (field_sel->ip_identification)
    {
        share_field_mode = 1;
    }
    else if (field_sel->ip_pkt_len)
    {
        share_field_mode = 2;
    }
    switch (share_field_mode)
    {
        case 0:
            p_l3_info->vrfid = pkey_d->uShareField_&0x3FFF;
            break;
        case 1:
            p_l3_info->ipv4.ip_identification = pkey_d->uShareField_;
            break;
        default:/*case 2:*/
            p_l3_info->ipv4.ip_pkt_len = pkey_d->uShareField_&0x3FFF;
            break;
    }
    p_data->fid = pkey_d->vsiId; /* TMM ...*/
    return CTC_E_NONE;
}

int32
_sys_at_ipfix_decode_ipv6_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv6_field_sel_t *field_sel = &field_sel_tmp.u.ipv6;
    uint32 merge_data[2] = {0};
    sys_at_ipfix_ipv6_hashkey_decode_t *pkey_d = (sys_at_ipfix_ipv6_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel_tmp));

    p_data->hash_salt = pkey_d->ipfixHashSalt_0_7 | (pkey_d->ipfixHashSalt_8_11 << 8);

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));

    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }

    p_data->l3_info.ipv6.dscp = pkey_d->dscp;
    p_data->l4_info.type.ip_protocol = pkey_d->layer3HeaderProtocol;
    p_data->l4_info.aware_tunnel_info_en = pkey_d->isMergeKey;

    if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP ==  p_data->l4_info.type.ip_protocol ) && (field_sel->icmp_type || field_sel->icmp_code))
    {
        p_data->l4_info.icmp.icmpcode = (pkey_d->uL4__0_29>>16)&0xff;
        p_data->l4_info.icmp.icmp_type = pkey_d->uL4__0_29>>24 | (pkey_d->uL4__30_31<<6);
    }
    else if(field_sel->igmp_type)
    {
        p_data->l4_info.igmp.igmp_type = pkey_d->uL4__0_29>>24 | (pkey_d->uL4__30_31<<6);
    }
    else if((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP ==  p_data->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP == p_data->l4_info.type.ip_protocol))
            && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
        p_data->l4_info.l4_port.dest_port = pkey_d->uL4__0_29&0xffff;
        p_data->l4_info.l4_port.source_port = pkey_d->uL4__0_29>>16 | (pkey_d->uL4__30_31<<14);
    }

    if(!p_data->l4_info.aware_tunnel_info_en)
    {
        if (field_sel->gre_key || field_sel->nvgre_key)
        {
            p_data->l4_info.gre_key = pkey_d->uL4__0_29 | (pkey_d->uL4__30_31<<30);
        }
        else if (field_sel->vxlan_vni)
        {
            p_data->l4_info.vni = pkey_d->uL4__0_29&0xFFFFFF;
        }
    }

    p_data->l3_info.ipv6.ipsa[0] = (pkey_d->ipSa_90_116>>6) |  (pkey_d->ipSa_117_127<<21);
    p_data->l3_info.ipv6.ipsa[1] = (pkey_d->ipSa_52_83>>12) |  (pkey_d->ipSa_84_89<<20)  | (pkey_d->ipSa_90_116<<26);
    p_data->l3_info.ipv6.ipsa[2] = (pkey_d->ipSa_20_51>>12) |  (pkey_d->ipSa_52_83<<20);
    p_data->l3_info.ipv6.ipsa[3] = pkey_d->ipSa_0_19 |  (pkey_d->ipSa_20_51<<20);

    p_data->l3_info.ipv6.ipda[0] = pkey_d->ipDa_89_115>>7 |(pkey_d->ipDa_116_127<<20);
    p_data->l3_info.ipv6.ipda[1] = pkey_d->ipDa_51_82>>13 | (pkey_d->ipDa_83_88<<19) | (pkey_d->ipDa_89_115<<25);
    p_data->l3_info.ipv6.ipda[2] = pkey_d->ipDa_19_50>>13 | (pkey_d->ipDa_51_82<<19);
    p_data->l3_info.ipv6.ipda[3] = pkey_d->ipDa_0_18 | (pkey_d->ipDa_19_50<<19);

    if (field_sel->src_cid)
    {
        p_data->src_cid = pkey_d->srcCategoryId_0_12 | (pkey_d->srcCategoryId_13_15<<13);
        if (pkey_d->srcCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    if (field_sel->dst_cid)
    {
        p_data->dst_cid = pkey_d->destCategoryId;
        if (pkey_d->destCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    if (field_sel->ip_frag)
    {
        p_data->l3_info.ip_frag = SYS_IPFIX_UNMAP_IP_FRAG(pkey_d->fragInfo);
    }
    if (field_sel->ecn)
    {
        p_data->l3_info.ipv6.ecn = pkey_d->ecn;
    }
    if (field_sel->ttl)
    {
        p_data->l3_info.ipv6.ttl = pkey_d->ttl;
    }
    if (field_sel->flow_label)
    {
        p_data->l3_info.ipv6.flow_label = pkey_d->ipv6FlowLabel_0_18 | (pkey_d->ipv6FlowLabel_19_19<<19);
    }
    if (field_sel->tcp_flags)
    {
        p_data->l4_info.tcp_flags = pkey_d->tcpFlags;
    }
    if (p_data->l4_info.aware_tunnel_info_en)
    {
        merge_data[0]=pkey_d->mergeData_0_27 | (pkey_d->mergeData_28_31<<28);
        switch (pkey_d->mergeDataType)
        {
            case SYS_IPFIX_MERGE_TYPE_VXLAN:
                p_data->l4_info.vni = merge_data[0]&0xFFFFFF;
                break;
            case SYS_IPFIX_MERGE_TYPE_GRE:
                p_data->l4_info.gre_key = merge_data[0];
                break;
            default:
                break;
        }
    }
    p_data->l3_info.ipv6.ipda_masklen = field_sel->ip_da_mask;
    p_data->l3_info.ipv6.ipsa_masklen = field_sel->ip_sa_mask;
    p_data->fid = pkey_d->vsiId; /* TMM ...*/
    if(field_sel->vrfid)
    {
        p_data->l3_info.vrfid = pkey_d->vrfId_0_6 | (pkey_d->vrfId_7_13 << 7);
    }
    return CTC_E_NONE;
}


int32
_sys_at_ipfix_decode_l2l3_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_l2_l3_field_sel_t *field_sel = &field_sel_tmp.u.l2_l3;

    hw_mac_addr_t             mac_sa   = { 0 };
    hw_mac_addr_t             mac_da   = { 0 };
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    sys_at_ipfix_l2l3_hashkey_decode_t *pkey_d = (sys_at_ipfix_l2l3_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_L2_L3, &field_sel_tmp));

    p_data->hash_salt = pkey_d->ipfixHashSalt;

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);

    p_data->ether_type = pkey_d->etherType_0_9 | (pkey_d->etherType_10_15 <<10);

    if (field_sel->ctag_cfi||field_sel->ctag_cos||field_sel->ctag_vlan)
    {
        p_data->cvlan = pkey_d->cvlanId;
        p_data->flags |= CTC_IPFIX_DATA_CVLAN_TAGGED;
    }
    p_data->cvlan_prio = pkey_d->cvtagCos;
    p_data->cvlan_cfi = pkey_d->cvtagCfi;

    if (field_sel->stag_cfi||field_sel->stag_cos||field_sel->stag_vlan)
    {
        p_data->svlan = pkey_d->svlanId;
        p_data->flags |= CTC_IPFIX_DATA_SVLAN_TAGGED;
    }
    p_data->svlan_prio = pkey_d->svtagCos;
    p_data->svlan_cfi = pkey_d->svtagCfi;

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16<<15));
    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16<<15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16<<15));
    }

    mac_sa[0]= pkey_d->macSa_0_31;
    mac_sa[1]= pkey_d->macSa_32_47;
    mac_da[0] = pkey_d->macDa_0_14 | (pkey_d->macDa_15_20<<15) | (pkey_d->macDa_21_47<<21) ;
    mac_da[1] = pkey_d->macDa_21_47>>11;

    if (field_sel->mac_sa)
    {
        SYS_USW_SET_USER_MAC(p_data->src_mac, mac_sa);
    }
    if (field_sel->mac_da)
    {
        SYS_USW_SET_USER_MAC(p_data->dst_mac, mac_da);
    }

    /* parser l3 information */

    if (field_sel->dst_cid)
    {
        p_data->dst_cid = pkey_d->destCategoryId;
        if (pkey_d->destCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }

    if (field_sel->src_cid)
    {
        p_data->src_cid = pkey_d->srcCategoryId_0_0 | (pkey_d->srcCategoryId_1_15<<1);
        if (pkey_d->srcCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    if (p_data->ether_type == IPV4_ETHER_TYPE || (!field_sel->eth_type && !field_sel->arp_code))
    {
        if (field_sel->ip_da)
        {
            p_l3_info->ipv4.ipda = pkey_d->uL3__0_21 | (pkey_d->uL3__22_53<<22);
            p_l3_info->ipv4.ipda_masklen = field_sel->ip_da_mask;
        }
        if (field_sel->ip_sa)
        {
            p_l3_info->ipv4.ipsa = (pkey_d->uL3__22_53>>10) | (pkey_d->uL3__54_59<<22) | (pkey_d->uL3__60_86<<28);
            p_l3_info->ipv4.ipsa_masklen = field_sel->ip_sa_mask;
        }
    }
    if(field_sel->ttl)
    {
        p_l3_info->ipv4.ttl = (pkey_d->uL3__60_86>>10 ) ;
    }
    if(field_sel->dscp)
    {
        p_l3_info->ipv4.dscp = (pkey_d->uL3__60_86>>4)&0x3F;
    }
    if(field_sel->ecn)
    {
        p_l3_info->ipv4.ecn = (pkey_d->uL3__60_86>>18)&0x3;
    }

    if(field_sel->label_num)
    {
        p_l3_info->mpls.label_num = (pkey_d->uL3__87_99>>9)&0xF;
    }
    if(field_sel->mpls_label0_exp)
    {
        p_l3_info->mpls.label[0].exp = (pkey_d->uL3__60_86>>13)&0x7;
    }
    if(field_sel->mpls_label0_label)
    {
        p_l3_info->mpls.label[0].label = (pkey_d->uL3__60_86 >> 16) | ((pkey_d->uL3__87_99 & 0x1FF) << 11);
    }
    if(field_sel->mpls_label0_s)
    {
        p_l3_info->mpls.label[0].sbit = (pkey_d->uL3__60_86>>12) & 0x1;
    }
    if(field_sel->mpls_label0_ttl)
    {
        p_l3_info->mpls.label[0].ttl = (pkey_d->uL3__60_86>>4)&0xFF;
    }
    if(field_sel->mpls_label1_exp)
    {
        p_l3_info->mpls.label[1].exp = (pkey_d->uL3__22_53>>19)&0x7;
    }
    if(field_sel->mpls_label1_label)
    {
        p_l3_info->mpls.label[1].label = pkey_d->uL3__22_53>>22 | ((pkey_d->uL3__54_59)<<10) | ((pkey_d->uL3__60_86&0xF)<<16);
    }
    if(field_sel->mpls_label1_s)
    {
        p_l3_info->mpls.label[1].sbit = (pkey_d->uL3__22_53>>18)&0x1;
    }
    if(field_sel->mpls_label1_ttl)
    {
        p_l3_info->mpls.label[1].ttl = (pkey_d->uL3__22_53>>10)&0xFF;
    }
    if(field_sel->mpls_label2_exp)
    {
        p_l3_info->mpls.label[2].exp = (pkey_d->uL3__0_21>>9)&0x7;
    }
    if(field_sel->mpls_label2_label)
    {
        p_l3_info->mpls.label[2].label = pkey_d->uL3__0_21>>12 | ((pkey_d->uL3__22_53&0x3FF)<<10);
    }
    if(field_sel->mpls_label2_s)
    {
        p_l3_info->mpls.label[2].sbit = (pkey_d->uL3__0_21>>8)&0x1;
    }
    if(field_sel->mpls_label2_ttl)
    {
        p_l3_info->mpls.label[2].ttl = pkey_d->uL3__0_21&0xFF;
    }

    if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP == pkey_d->layer3HeaderProtocol) && (field_sel->icmp_code || field_sel->icmp_type))
    {
        p_l4_info->icmp.icmpcode = pkey_d->uL4__0_29>>24 | (pkey_d->uL4__30_39&0x3)<<6;
        p_l4_info->icmp.icmp_type = (pkey_d->uL4__30_39>>2)&0xFF;
    }
    else if((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP == pkey_d->layer3HeaderProtocol) &&field_sel->igmp_type)
    {
        p_l4_info->igmp.igmp_type = (pkey_d->uL4__30_39>>2)&0xFF;
    }
    else if((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP == pkey_d->layer3HeaderProtocol || SYS_L4_PROTOCOL_UDP == pkey_d->layer3HeaderProtocol ))
            && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
        p_l4_info->l4_port.dest_port = (pkey_d->uL4__0_29>>8)&0xFFFF;
        p_l4_info->l4_port.source_port = pkey_d->uL4__0_29>>24 | (pkey_d->uL4__30_39&0x3FF)<<6;
    }

    /* process l4 information */
    p_l4_info->aware_tunnel_info_en = pkey_d->isMergeKey;

    if (p_l4_info->aware_tunnel_info_en)
    {
        switch (pkey_d->mergeDataType)
        {
            case 1:
                p_l4_info->vni = pkey_d->mergeData_0_18 | (pkey_d->mergeData_19_31<<19);
                break;
            case 2:
                p_l4_info->gre_key = pkey_d->mergeData_0_18 | (pkey_d->mergeData_19_31<<19);
                break;
            default:
                break;
        }
    }
    else
    {
        if (field_sel->gre_key || field_sel->nvgre_key)
        {
            p_l4_info->gre_key = pkey_d->uL4__0_29 | (pkey_d->uL4__30_39&0x3) << 30;
        }
        else if (field_sel->vxlan_vni)
        {
            p_l4_info->vni = pkey_d->uL4__0_29&0xFFFFFF;
        }
    }
    p_l4_info->type.ip_protocol = pkey_d->layer3HeaderProtocol;
    if (field_sel->tcp_flags)
    {
        p_l4_info->tcp_flags = pkey_d->uL4__0_29&0xFF;
    }
    if (field_sel->ip_frag)
    {
        p_l3_info->ip_frag = SYS_IPFIX_UNMAP_IP_FRAG((pkey_d->uL3__60_86 >> 20)&0x3);
    }
    if (field_sel->ip_identification)
    {
        p_l3_info->ipv4.ip_identification = (pkey_d->uL3__60_86 >> 22) | ((pkey_d->uL3__87_99&0x7FF) << 5);
    }
    if (field_sel->vrfid)
    {
        p_l3_info->vrfid = pkey_d->vrfId;
    }
    if (p_data->ether_type == ARP_ETHER_TYPE)
    {
        if (field_sel->ip_sa)
        {
            p_l3_info->arp.sender_ip = (pkey_d->uL3__22_53 >> 26) | (pkey_d->uL3__54_59 << 6) | (pkey_d->uL3__60_86 << 12);
        }
        if (field_sel->ip_da)
        {
            p_l3_info->arp.target_ip = (pkey_d->uL3__0_21 >> 16) | (pkey_d->uL3__22_53 << 6);
        }
        if (field_sel->arp_code)
        {
            p_l3_info->arp.op_code = (pkey_d->uL3__0_21&0xFFFF);
        }
        if (field_sel->arp_mac_sa)
        {
            SYS_USW_SET_USER_MAC(p_data->l3_info.arp.sender_mac, mac_sa);
        }
        if (field_sel->arp_mac_da)
        {
            SYS_USW_SET_USER_MAC(p_data->l3_info.arp.target_mac, mac_da);
        }
    }
    if (field_sel->fid)
    {
        p_data->fid = pkey_d->vsiId_0_5 | (pkey_d->vsiId_6_14 << 6) ; /* TMM ...*/
    }
    return CTC_E_NONE;
}

int32
_sys_at_ipfix_decode_mpls_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_mpls_field_sel_t *field_sel = &field_sel_tmp.u.mpls;
    ctc_ipfix_l3_info_t* p_l3_info;
    sys_at_ipfix_mpls_hashkey_decode_t *pkey_d = (sys_at_ipfix_mpls_hashkey_decode_t*)p_key;

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_MPLS, &field_sel_tmp));

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }

    p_l3_info->mpls.label_num = (pkey_d->labelNum_0_1) | (pkey_d->labelNum_2_3 <<2);
    if (p_l3_info->mpls.label_num > CTC_IPFIX_LABEL_NUM)
    {
        return CTC_E_INVALID_PARAM;
    }

    p_l3_info->mpls.label[0].exp = pkey_d->mplsExp0;
    p_l3_info->mpls.label[0].label = pkey_d->mplsLabel0;
    p_l3_info->mpls.label[0].sbit = pkey_d->mplsSbit0;
    p_l3_info->mpls.label[0].ttl = pkey_d->mplsTtl0_0_5 | (pkey_d->mplsTtl0_6_7<<6);
    p_l3_info->mpls.label[1].exp = pkey_d->mplsExp1;
    p_l3_info->mpls.label[1].label = pkey_d->mplsLabel1;
    p_l3_info->mpls.label[1].sbit = pkey_d->mplsSbit1;
    p_l3_info->mpls.label[1].ttl = pkey_d->mplsTtl1_0_5 | (pkey_d->mplsTtl1_6_7<<6);
    p_l3_info->mpls.label[2].exp = pkey_d->mplsExp2;
    p_l3_info->mpls.label[2].label = pkey_d->mplsLabel2;
    p_l3_info->mpls.label[2].sbit = pkey_d->mplsSbit2;
    p_l3_info->mpls.label[2].ttl = pkey_d->mplsTtl2_0_5 | (pkey_d->mplsTtl2_6_7 << 6);
    p_data->fid = pkey_d->vsiId_0_3 |( pkey_d->vsiId_4_14 <<4); /* TMM ...*/
    return CTC_E_NONE;
}


STATIC int32
_sys_at_ipfix_decode_udf_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_udf_field_sel_t *field_sel = &field_sel_tmp.u.udf;

    uint32 hw_udf[4] = {0};
    sys_at_ipfix_udf_hashkey_decode_t *pkey_d = (sys_at_ipfix_udf_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id =  pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_UDF, &field_sel_tmp));

    p_data->hash_salt = (pkey_d->ipfixHashSalt_0_8) | (pkey_d->ipfixHashSalt_9_11 << 9);

    hw_udf[0] = pkey_d->udfData_0_21 | ((pkey_d->udfData_22_53&0x3FF)<<22);
    hw_udf[1] = (pkey_d->udfData_22_53>>10) | (pkey_d->udfData_54_85<<22);
    hw_udf[2] = (pkey_d->udfData_54_85>>10) | (pkey_d->udfData_86_91<<22)  | (pkey_d->udfData_92_118<<28);
    hw_udf[3] = (pkey_d->udfData_92_118>>4) | (pkey_d->udfData_119_127<<23);

    SYS_USW_SET_USR_UDF(1,  p_data->udf, hw_udf);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_id(lchip,(pkey_d->udfHitIndex),&p_data->udf_id));

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16<<15));
    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16<<15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16<<15));
    }

    return CTC_E_NONE;
}


STATIC int32
_sys_at_ipfix_decode_udf_short_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    uint32 hw_udf[4] = {0};
    sys_at_ipfix_udf_short_hashkey_decode_t *pkey_d = (sys_at_ipfix_udf_short_hashkey_decode_t*)p_key;
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id =  pkey_d->ipfixCfgProfileId;

    p_data->hash_salt = pkey_d->ipfixHashSalt;
    hw_udf[0] = pkey_d->udfData_0_6 | ((pkey_d->udfData_7_38&0x1FFFFFF) << 7);
    hw_udf[1] = (pkey_d->udfData_7_38 >> 25) | ((pkey_d->udfData_39_70&0x1FFFFFF) << 7);
    hw_udf[2] = (pkey_d->udfData_39_70 >> 25) | (pkey_d->udfData_71_79 << 7);

    SYS_USW_SET_USR_UDF_SHORT(lchip,  p_data->udf, hw_udf);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_id(lchip, pkey_d->udfHitIndex, &p_data->udf_id));

    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_decode_v4_short_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv4_field_sel_t *field_sel = &field_sel_tmp.u.ipv4;
    ctc_ipfix_l3_info_t* p_l3_info;
    ctc_ipfix_l4_info_t* p_l4_info;
    sys_at_ipfix_ipv4_short_hashkey_decode_t *pkey_d = (sys_at_ipfix_ipv4_short_hashkey_decode_t*)p_key;
    uint32 tmp_mask = 0;
    uint32 tmp_ip_protocol = 0;
    uint8 drv_l4_type = 0;
    uint8 ctc_l4_type = 0;

    p_l3_info = (ctc_ipfix_l3_info_t*)&(p_data->l3_info);
    p_l4_info = (ctc_ipfix_l4_info_t*)&(p_data->l4_info);
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;


    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, (pkey_d->isIp?CTC_IPFIX_KEY_HASH_IPV4_SINGLE:CTC_IPFIX_KEY_HASH_MPLS_SINGLE), &field_sel_tmp));

    if(pkey_d->isIp)
    {
        p_l3_info->ipv4.ipda = (pkey_d->uL3__30_61 >> 6) | (pkey_d->uL3__62_93 << 26);
        p_l3_info->ipv4.ipda_masklen = field_sel->ip_da_mask;
        p_l3_info->ipv4.ipsa = (pkey_d->uL3__62_93>>6) | (pkey_d->uL3__94_99<<26);
        p_l3_info->ipv4.ipsa_masklen = field_sel->ip_sa_mask;

        drv_l4_type = (pkey_d->uL3__30_61>>2)&0xF;
        if (field_sel->ip_protocol)
        {
            ctc_l4_type = sys_usw_l4_type_map(lchip, drv_l4_type, FALSE);
            (void)sys_usw_acl_map_l4_type_to_ip_protocol(lchip, CTC_PARSER_L3_TYPE_IPV4, ctc_l4_type, &tmp_ip_protocol, &tmp_mask);
            p_l4_info->type.ip_protocol = tmp_ip_protocol;
        }
        if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_ICMP ==  tmp_ip_protocol) && (field_sel->icmp_code || field_sel->icmp_type))
        {
            p_l4_info->icmp.icmpcode = (pkey_d->uL3__0_29>>16)&0xFF;
            p_l4_info->icmp.icmp_type = ((pkey_d->uL3__0_29>>24)&0xff) |((pkey_d->uL3__30_61 & 0x3) <<6);
        }
        else if((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV4_IGMP ==  tmp_ip_protocol) && field_sel->igmp_type)
        {
            p_l4_info->igmp.igmp_type = ((pkey_d->uL3__0_29>>24)&0xff) |((pkey_d->uL3__30_61 & 0x3) <<6);
        }
        else if ((!field_sel->ip_protocol || (SYS_L4_PROTOCOL_TCP ==  tmp_ip_protocol|| SYS_L4_PROTOCOL_UDP == tmp_ip_protocol))
                && (field_sel->l4_src_port || field_sel->l4_dst_port))
        {
            p_l4_info->l4_port.dest_port = (pkey_d->uL3__0_29 &0xFFFF);
            p_l4_info->l4_port.source_port = (pkey_d->uL3__0_29>>16)|((pkey_d->uL3__30_61 &0x3) << 14);
        }
    }
    else
    {
        p_l3_info->mpls.label_num = (pkey_d->uL3__94_99>>2)&0xF;
        if (p_l3_info->mpls.label_num > CTC_IPFIX_LABEL_NUM)
        {
            return CTC_E_INVALID_PARAM;
        }
        p_l3_info->mpls.label[0].exp = (pkey_d->uL3__0_29>>20)&0x7;
        p_l3_info->mpls.label[0].label = pkey_d->uL3__0_29 & 0xfffff;
        p_l3_info->mpls.label[0].sbit = (pkey_d->uL3__0_29>>23)&0x1;
        p_l3_info->mpls.label[0].ttl = ((pkey_d->uL3__0_29>>24)&0xFF) | ((pkey_d->uL3__30_61&0x3)<<6);
        p_l3_info->mpls.label[1].exp = (pkey_d->uL3__30_61>>22)&0x7;
        p_l3_info->mpls.label[1].label = (pkey_d->uL3__30_61>>2)&0xfffff;
        p_l3_info->mpls.label[1].sbit = (pkey_d->uL3__30_61>>25)&0x1;
        p_l3_info->mpls.label[1].ttl = ((pkey_d->uL3__30_61>>26)&0xFF) | ((pkey_d->uL3__62_93&0x3)<<6);
        p_l3_info->mpls.label[2].exp = (pkey_d->uL3__62_93>>22)&0x7;
        p_l3_info->mpls.label[2].label = (pkey_d->uL3__62_93>>2)&0xfffff;
        p_l3_info->mpls.label[2].sbit = (pkey_d->uL3__62_93>>25)&0x1;
        p_l3_info->mpls.label[2].ttl = ((pkey_d->uL3__62_93>>26)&0xFF) | ((pkey_d->uL3__94_99&0x3)<<6);
        p_data->key_type = CTC_IPFIX_KEY_HASH_MPLS_SINGLE;
    }
    if (field_sel->gport)
    {
        p_data->gport = ((pkey_d->flexData_15_15 << 15) | pkey_d->flexData_0_14);
    }
    else if (field_sel->fid)
    {
        p_data->fid = pkey_d->flexData_0_14;
    }
    else if (field_sel->vrfid)
    {
        if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x7fff) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x4000))
        {
            p_l3_info->vrfid = (pkey_d->flexData_15_15 << 13) | (pkey_d->flexData_0_14 >> 2);
            p_data->hash_salt = (pkey_d->flexData_0_14 & 0x3);
        }
        else if ( (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x4000) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x3ff))
        {
            p_l3_info->vrfid = (pkey_d->flexData_15_15 << 9) | (pkey_d->flexData_0_14 >> 6);
            p_data->hash_salt = (pkey_d->flexData_0_14 & 0x3f);
        }
        else if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x3ff) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x7f))
        {
            p_l3_info->vrfid = (pkey_d->flexData_15_15 << 5) | (pkey_d->flexData_0_14 >> 10);
            p_data->hash_salt = (pkey_d->flexData_0_14 & 0x3ff);
        }
        else if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x7f) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x10))
        {
            p_l3_info->vrfid = (pkey_d->flexData_15_15 << 3) | (pkey_d->flexData_0_14 >> 12);
            p_data->hash_salt = (pkey_d->flexData_0_14 & 0xfff);
        }
    }
    else/*default hashsalt select enable*/
    {
        p_data->hash_salt = (pkey_d->flexData_0_14 & 0xfff);
    }
    return CTC_E_NONE;
}


STATIC int32
_sys_at_ipfix_decode_v6_short_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv6_field_sel_t *field_sel = &field_sel_tmp.u.ipv6;

    sys_at_ipfix_ipv6_short_hashkey_decode_t *pkey_d = (sys_at_ipfix_ipv6_short_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6_SINGLE, &field_sel_tmp));

    p_data->hash_salt = (pkey_d->ipfixHashSalt_0_6) | (pkey_d->ipfixHashSalt_7_11 << 7);
    p_data->l4_info.type.ip_protocol = pkey_d->layer3HeaderProtocol;
    if ((!field_sel->ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP ==  p_data->l4_info.type.ip_protocol) && (field_sel->icmp_type || field_sel->icmp_code))
    {
        p_data->l4_info.icmp.icmpcode = pkey_d->l4SourcePort&0xFF;
        p_data->l4_info.icmp.icmp_type = pkey_d->l4SourcePort>>8;
    }
    else if(field_sel->igmp_type)
    {
        p_data->l4_info.igmp.igmp_type =pkey_d->l4SourcePort>>8;
    }
    else if((!field_sel->ip_protocol ||(SYS_L4_PROTOCOL_TCP ==  p_data->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP == p_data->l4_info.type.ip_protocol))
            && (field_sel->l4_src_port || field_sel->l4_dst_port))
    {
        p_data->l4_info.l4_port.dest_port = pkey_d->l4DestPort_0_14 | pkey_d->l4DestPort_15_15<<15;
        p_data->l4_info.l4_port.source_port = pkey_d->l4SourcePort;
    }
    if (field_sel -> ipv6_low_en)
    {
        p_data->l3_info.ipv6.ipsa[2] = (pkey_d->ipSaPrefix_13_39 >> 19) | (pkey_d->ipSaPrefix_40_63 << 8);
        p_data->l3_info.ipv6.ipsa[3] = pkey_d->ipSaPrefix_0_6 | (pkey_d->ipSaPrefix_7_12 << 7) | ((pkey_d->ipSaPrefix_13_39 & 0x7ffff) << 13);

        p_data->l3_info.ipv6.ipda[2] = pkey_d->ipDaPrefix_7_38 >> 25 | pkey_d->ipDaPrefix_39_63 << 7;
        p_data->l3_info.ipv6.ipda[3] = pkey_d->ipDaPrefix_0_6 | (pkey_d->ipDaPrefix_7_38&0x1FFFFFF) << 7;
    }
    else
    {
        p_data->l3_info.ipv6.ipsa[0] = (pkey_d->ipSaPrefix_13_39 >> 19) | (pkey_d->ipSaPrefix_40_63 << 8);
        p_data->l3_info.ipv6.ipsa[1] = pkey_d->ipSaPrefix_0_6 | (pkey_d->ipSaPrefix_7_12 << 7) | ((pkey_d->ipSaPrefix_13_39 & 0x7ffff) << 13);

        p_data->l3_info.ipv6.ipda[0] = pkey_d->ipDaPrefix_7_38 >> 25 | pkey_d->ipDaPrefix_39_63 << 7;
        p_data->l3_info.ipv6.ipda[1] = pkey_d->ipDaPrefix_0_6 | (pkey_d->ipDaPrefix_7_38&0x1FFFFFF) << 7;
    }

    p_data->l3_info.ipv6.ipda_masklen = field_sel->ip_da_mask;
    p_data->l3_info.ipv6.ipsa_masklen = field_sel->ip_sa_mask;

    if(field_sel->fid)
    {
        p_data->fid = pkey_d->vsiId_0_3 | pkey_d->vsiId_4_14 << 4;
    }
    if(field_sel->vrfid)
    {
        p_data->l3_info.vrfid = pkey_d->vrfId;
    }

    return CTC_E_NONE;
}
#ifdef AT_TODO
STATIC int32
_sys_at_ipfix_decode_nsh_hashkey(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv6_field_sel_t *field_sel = &field_sel_tmp.u.ipv6;

    uint32 merge_data[2] = {0};
    sys_at_ipfix_nsh_hashkey_decode_t *pkey_d = (sys_at_ipfix_nsh_hashkey_decode_t*)p_key;
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    p_data->hash_salt = pkey_d->ipfixHashSalt;
    uint8 isipv4;/*tmp*/
    uint8 isipv6;/*tmp*/
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel_tmp));

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }

    p_data->l4_info.type.ip_protocol = pkey_d->layer3HeaderProtocol_0_1 | (pkey_d->layer3HeaderProtocol_2_7 << 2);
    p_data->l4_info.aware_tunnel_info_en = pkey_d->isMergeKey;

    if (field_sel->icmp_type || field_sel->icmp_code)
    {
        p_data->l4_info.icmp.icmpcode = (pkey_d->uL4__0_29 >> 16)&0xff;
        p_data->l4_info.icmp.icmp_type = pkey_d->uL4__0_29 >> 24 | (pkey_d->uL4__30_31 << 6);
    }
    else if (field_sel->igmp_type)
    {
        p_data->l4_info.igmp.igmp_type = pkey_d->uL4__0_29 >> 24 | (pkey_d->uL4__30_31 << 6);
    }
    else if (field_sel->l4_src_port || field_sel->l4_dst_port)
    {
        p_data->l4_info.l4_port.dest_port = pkey_d->uL4__0_29&0xffff;
        p_data->l4_info.l4_port.source_port = pkey_d->uL4__0_29 >> 16 | (pkey_d->uL4__30_31 << 14);
    }

    if (!p_data->l4_info.aware_tunnel_info_en)
    {
        if (field_sel->gre_key || field_sel->nvgre_key)
        {
            p_data->l4_info.gre_key = pkey_d->uL4__0_29 | (pkey_d->uL4__30_31 << 30);
        }
        else if (field_sel->vxlan_vni)
        {
            p_data->l4_info.vni = pkey_d->uL4__0_29&0xFFFFFF;
        }
    }
    isipv4 = pkey_d->isIpv4;/*tmp*/
    isipv6 = pkey_d->isIpv6;/*tmp*/
    /*ipv6*/
    if (isipv6)
    {
        p_data->l3_info.ipv6.ipsa[0] = (pkey_d->ipSa_80_111 >> 16) | (pkey_d->ipSa_112_117 << 16) | (pkey_d->ipSa_118_127 << 26);
        p_data->l3_info.ipv6.ipsa[1] = (pkey_d->ipSa_48_79 >> 16) |  (pkey_d->ipSa_80_111 << 16);
        p_data->l3_info.ipv6.ipsa[2] = (pkey_d->ipSa_16_47 >> 16) |  (pkey_d->ipSa_48_79 << 16);
        p_data->l3_info.ipv6.ipsa[3] = pkey_d->ipSa_0_15  |  (pkey_d->ipSa_16_47 << 16);
        p_data->l3_info.ipv6.ipsa_masklen = field_sel->ip_sa_mask;/*tmp*/

        p_data->l3_info.ipv6.ipda[0] = pkey_d->ipDa_79_110 >> 17 | (pkey_d->ipDa_111_116 << 15) | (pkey_d->ipDa_117_127 << 21);
        p_data->l3_info.ipv6.ipda[1] = pkey_d->ipDa_47_78 >> 17 | (pkey_d->ipDa_79_110 << 15);
        p_data->l3_info.ipv6.ipda[2] = pkey_d->ipDa_15_46 >> 17 | (pkey_d->ipDa_47_78  << 15);
        p_data->l3_info.ipv6.ipda[3] = pkey_d->ipDa_0_14 | (pkey_d->ipDa_15_46 << 15);
        p_data->l3_info.ipv6.ipda_masklen = field_sel->ip_da_mask;/*tmp*/
    }
    /*ipv4*/
    else if (isipv4)
    {
        p_data->l3_info.ipv4.ipsa = pkey_d->ipSa_0_15 | (pkey_d->ipSa_16_47 << 16);
        p_data->l3_info.ipv4.ipsa_masklen = field_sel->ip_sa_mask;

        p_data->l3_info.ipv4.ipda = pkey_d->ipDa_0_14 | (pkey_d->ipDa_15_46 << 15);
        p_data->l3_info.ipv4.ipda_masklen = field_sel->ip_da_mask;
    }

    if (field_sel->src_cid)
    {
        p_data->src_cid = pkey_d->srcCategoryId_0_12 | (pkey_d->srcCategoryId_13_15 << 13);
        if (pkey_d->srcCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    if (field_sel->dst_cid)
    {
        p_data->dst_cid = pkey_d->destCategoryId;
        if (pkey_d->destCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }
    if (field_sel->ecn)
    {
        p_data->l3_info.ipv6.ecn = pkey_d->ecn;
    }
    if (field_sel->tcp_flags)
    {
        p_data->l4_info.tcp_flags = pkey_d->tcpFlags;
    }
    if (p_data->l4_info.aware_tunnel_info_en)
    {
        merge_data[0] = pkey_d->mergeData_0_27 | (pkey_d->mergeData_28_31 << 28);
        switch (pkey_d->mergeDataType)
        {
            case SYS_IPFIX_MERGE_TYPE_VXLAN:
                p_data->l4_info.vni = merge_data[0]&0xFFFFFF;
                break;
            case SYS_IPFIX_MERGE_TYPE_GRE:
                p_data->l4_info.gre_key = merge_data[0];
                break;
            default:
                break;
        }
    }
    p_data->fid = pkey_d->vsiId;
    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_decode_nsh_short_key(uint8 lchip, ctc_ipfix_data_t* p_data, void* p_key)
{
    ctc_ipfix_hash_field_sel_t field_sel_tmp;
    ctc_ipfix_hash_ipv6_field_sel_t *field_sel = &field_sel_tmp.u.ipv6;
    sys_at_ipfix_nsh_short_hashkey_decode_t *pkey_d = (sys_at_ipfix_nsh_short_hashkey_decode_t*)p_key;
    sal_memset(&field_sel_tmp, 0, sizeof(ctc_ipfix_hash_field_sel_t));
    p_data->field_sel_id = pkey_d->flowFieldSel;
    p_data->profile_id = pkey_d->ipfixCfgProfileId;
    p_data->hash_salt = pkey_d->ipfixHashSalt;
    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_data->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel_tmp));

    if (field_sel->gport)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_GPORT;
        p_data->gport = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }
    else if (field_sel->logic_port)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_LOGIC_PORT;
        p_data->logic_port = pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15);
    }
    else if (field_sel->metadata)
    {
        p_data->port_type = CTC_IPFIX_PORT_TYPE_METADATA;
        p_data->logic_port = SYS_TMM_IPFIX_DECODE_METADATA(pkey_d->globalPort_0_14 | (pkey_d->globalPort_15_16 << 15));
    }

    if (field_sel->src_cid)
    {
        p_data->src_cid = pkey_d->srcCategoryId_0_12 | (pkey_d->srcCategoryId_13_15 << 13);
        if (pkey_d->srcCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_SRC_CID_VALID;
        }
    }
    if (field_sel->dst_cid)
    {
        p_data->dst_cid = pkey_d->destCategoryId;
        if (pkey_d->destCategoryIdClassfied)
        {
            p_data->flags |= CTC_IPFIX_DATA_DST_CID_VALID;
        }
    }

    return CTC_E_NONE;
}
#endif

STATIC int32
_sys_at_ipfix_encode_udf_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    uint32 cmd = 0;
    uint16 global_port = 0;
    uint16 udf_data_en[16] = {0};
    uint16  zero[16] = {0};
    uint16 udf_valid_en = 0;
    uint32 hw_udf[8] = {0};
    uint8  udfindexmatch_valid = 0;
    sys_acl_udf_info_t udf_info;
    DsIpfixUdfHashKey_m udf_key;
    IpfixUdfHashFieldSelect_m  hash_field;
    sal_memset(&udf_key, 0, sizeof(udf_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));

    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port, MCHIP_CAP(SYS_CAP_MAX_LOGIC_PORT));
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port, 0x7FFF );
        global_port = SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixUdfHashKey(V, ipfixHashSalt_f, &udf_key, p_key->hash_salt);
    SetDsIpfixUdfHashKey(V, hashKeyType0_f, &udf_key, SYS_IPFIX_HASH_TYPE_UDF);
    SetDsIpfixUdfHashKey(V, hashKeyType1_f, &udf_key, SYS_IPFIX_HASH_TYPE_UDF);
    SetDsIpfixUdfHashKey(V, flowFieldSel_f, &udf_key, p_key->field_sel_id);
    SetDsIpfixUdfHashKey(V, ipfixCfgProfileId_f, &udf_key, p_key->profile_id);
    SetDsIpfixUdfHashKey(V, globalPort_f, &udf_key, global_port);

    cmd = DRV_IOR(IpfixUdfHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    GetIpfixUdfHashFieldSelect(A, udfDataEn_f, &hash_field, udf_data_en);
    udfindexmatch_valid = GetIpfixUdfHashFieldSelect(V, udfHitIndexEn_f, &hash_field);
    udf_valid_en = GetIpfixUdfHashFieldSelect(V, udfValidEn_f, &hash_field);
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_info(lchip, p_key->udf_id, &udf_info));
    if(sal_memcmp(udf_data_en, zero, 16*sizeof(uint16)) || udfindexmatch_valid || udf_valid_en)
    {
        SYS_USW_SET_HW_UDF(1, hw_udf,p_key->udf);
        SetDsIpfixUdfHashKey(A, udfData_f, &udf_key, hw_udf);
    }
    SetDsIpfixUdfHashKey(V, udfValid_f, &udf_key, (udf_valid_en & ((1 << udf_info.scl_offset_num) -1)));
    SetDsIpfixUdfHashKey(V, udfHitIndex_f, &udf_key, udf_info.udf_hit_index);
    sal_memcpy((uint8*)p_data, (uint8*)&udf_key, sizeof(udf_key));
    return CTC_E_NONE;
}


STATIC int32
_sys_at_ipfix_encode_udf_short_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{

    uint32 cmd = 0;
    uint16 udf_data_en[16] = {0};
    uint16  zero[16] = {0};
    uint16 udf_valid_en = 0;
    uint32 hw_udf[6] = {0};
    uint8  udfindexmatch_valid = 0;
    sys_acl_udf_info_t udf_info;
    DsIpfixUdfShortHashKey_m udf_short_key;
    IpfixUdfShortHashFieldSelect_m  hash_field;
    sal_memset(&udf_short_key, 0, sizeof(udf_short_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    SetDsIpfixUdfShortHashKey(V, hashKeyType_f, &udf_short_key, SYS_IPFIX_HASH_TYPE_UDF_SHORT);
    SetDsIpfixUdfShortHashKey(V, flowFieldSel_f, &udf_short_key, p_key->field_sel_id);
    SetDsIpfixUdfShortHashKey(V, ipfixCfgProfileId_f, &udf_short_key, p_key->profile_id);
    SetDsIpfixUdfShortHashKey(V, ipfixHashSalt_f, &udf_short_key, p_key->hash_salt);

    cmd = DRV_IOR(IpfixUdfShortHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, cmd, &hash_field));

    GetIpfixUdfShortHashFieldSelect(A, udfDataEn_f, &hash_field, udf_data_en);
    udf_valid_en = GetIpfixUdfShortHashFieldSelect(V, udfValidEn_f, &hash_field);
    udfindexmatch_valid = GetIpfixUdfShortHashFieldSelect(V, udfHitIndexEn_f, &hash_field);

    if(sal_memcmp(udf_data_en, zero, 16*sizeof(uint16)) || udfindexmatch_valid || udf_valid_en)
    {
        SYS_USW_SET_HW_UDF_SHORT(lchip, hw_udf,p_key->udf);
        SetDsIpfixUdfShortHashKey(A, udfData_f, &udf_short_key, hw_udf);
    }
    CTC_ERROR_RETURN(sys_usw_acl_get_udf_info(lchip, p_key->udf_id, &udf_info));
    SetDsIpfixUdfShortHashKey(V, udfValid_f, &udf_short_key, (udf_valid_en & ((1 << udf_info.scl_offset_num) -1)));
    SetDsIpfixUdfShortHashKey(V, udfHitIndex_f, &udf_short_key, udf_info.udf_hit_index);

    sal_memcpy((uint8*)p_data, (uint8*)&udf_short_key, sizeof(udf_short_key));

    return CTC_E_NONE;
}
STATIC int32
_sys_at_ipfix_encode_v4_short_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL3Ipv4ShortHashKey_m ipv4_short_key;
    IpfixShortIpv4HashFieldSelect_m hash_field;
    uint16 l4_srcport = 0;
    uint32 cmd = 0;
    ctc_ipfix_hash_field_sel_t field_sel;
    uint8 is_ip = 0;
    uint32 tmp_mask = 0;
    uint32 ctc_l4_type = 0;
    uint32 drv_l4_type = 0;

    sal_memset(&ipv4_short_key, 0, sizeof(ipv4_short_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    sal_memset(&field_sel, 0, sizeof(ctc_ipfix_hash_field_sel_t));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, p_key->key_type, &field_sel));/*ipv4 single key or mpls single key*/
    SetDsIpfixL3Ipv4ShortHashKey(V, hashKeyType_f, &ipv4_short_key, SYS_IPFIX_HASH_TYPE_IPV4_SHORT);
    SetDsIpfixL3Ipv4ShortHashKey(V, flowFieldSel_f, &ipv4_short_key, p_key->field_sel_id);
    SetDsIpfixL3Ipv4ShortHashKey(V, ipfixCfgProfileId_f, &ipv4_short_key, p_key->profile_id);

    cmd = DRV_IOR(IpfixShortIpv4HashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    if (field_sel.u.ipv4.gport)
    {
        SetDsIpfixL3Ipv4ShortHashKey(V, flexData_f, &ipv4_short_key, p_key->gport);
    }
    else if (field_sel.u.ipv4.fid)
    {
        SetDsIpfixL3Ipv4ShortHashKey(V, flexData_f, &ipv4_short_key, p_key->fid);
    }
    else if (field_sel.u.ipv4.vrfid)
    {
        if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x7fff) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x4000))
        {
            SetDsIpfixL3Ipv4ShortHashKey(V, flexData_f, &ipv4_short_key, (p_key->l3_info.vrfid << 2) | (p_key->hash_salt & 0x3));
        }
        else if ( (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x4000) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x3ff))
        {
            SetDsIpfixL3Ipv4ShortHashKey(V, flexData_f, &ipv4_short_key, (p_key->l3_info.vrfid << 6) | (p_key->hash_salt & 0x3f));
        }
        else if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x3ff) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x7f))
        {
            SetDsIpfixL3Ipv4ShortHashKey(V, flexData_f, &ipv4_short_key, (p_key->l3_info.vrfid << 10) | (p_key->hash_salt & 0x3ff));
        }
        else if ((MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) <= 0x7f) && (MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID) > 0x10))
        {
            SetDsIpfixL3Ipv4ShortHashKey(V, flexData_f, &ipv4_short_key, (p_key->l3_info.vrfid << 12) | (p_key->hash_salt & 0xfff));
        }
    }
    else if(0x2 == GetIpfixShortIpv4HashFieldSelect(V, flexDataType_f,  &hash_field))
    {
        SetDsIpfixL3Ipv4ShortHashKey(V, flexData_f, &ipv4_short_key, p_key->hash_salt);
    }

    cmd =DRV_IOR(IpfixShortIpv4HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    is_ip = GetIpfixShortIpv4HashFieldSelect(V, isIpEn_f, &hash_field);
    SetDsIpfixL3Ipv4ShortHashKey(V, isIp_f, &ipv4_short_key, is_ip);
    if (is_ip)
    {
        /*gen l3 key*/
        if (p_key->l3_info.ipv4.ipda != 0)
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipda_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_ipDa_f, &ipv4_short_key, p_key->l3_info.ipv4.ipda);
        }
        if (p_key->l3_info.ipv4.ipsa != 0 )
        {
            IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipsa_masklen);
            IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_ipSa_f, &ipv4_short_key, p_key->l3_info.ipv4.ipsa);
        }
        CTC_ERROR_RETURN(sys_usw_acl_map_ip_protocol_to_l4_type(lchip, CTC_PARSER_L3_TYPE_IPV4, p_key->l4_info.type.ip_protocol,
                                                           &ctc_l4_type, &tmp_mask));
        /*gen l4 key*/
        if(field_sel.u.ipv4.ip_protocol)
        {
            drv_l4_type = sys_usw_l4_type_map(lchip, ctc_l4_type, TRUE);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_layer4Type_f, &ipv4_short_key, drv_l4_type);
        }

        if ((!field_sel.u.ipv4.ip_protocol || CTC_IPFIX_L4_TYPE_ICMP == ctc_l4_type) && (field_sel.u.ipv4.icmp_code || field_sel.u.ipv4.icmp_type))
        {
            l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
            l4_srcport |=  (((p_key->l4_info.icmp.icmp_type) & 0xff) << 8);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4SourcePort_f, &ipv4_short_key, l4_srcport);
        }
        else if ((!field_sel.u.ipv4.ip_protocol || CTC_IPFIX_L4_TYPE_IGMP ==   ctc_l4_type) && field_sel.u.ipv4.igmp_type)
        {
            l4_srcport = p_key->l4_info.igmp.igmp_type << 8;
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4SourcePort_f, &ipv4_short_key, l4_srcport);
        }
        else if ((!field_sel.u.ipv4.ip_protocol || CTC_IPFIX_L4_TYPE_TCP == ctc_l4_type || CTC_IPFIX_L4_TYPE_UDP == ctc_l4_type)
            && (field_sel.u.ipv4.l4_src_port || field_sel.u.ipv4.l4_dst_port))
        {
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4DestPort_f, &ipv4_short_key, p_key->l4_info.l4_port.dest_port);
            SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gIpv4_l4SourcePort_f, &ipv4_short_key, p_key->l4_info.l4_port.source_port);
        }
    }
    else
    {
        /*gen mpls key*/
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_labelNum_f, &ipv4_short_key, p_key->l3_info.mpls.label_num);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsExp0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].exp);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsLabel0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].label);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsSbit0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].sbit);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsTtl0_f, &ipv4_short_key, p_key->l3_info.mpls.label[0].ttl);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsExp1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].exp);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsLabel1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].label);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsSbit1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].sbit);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsTtl1_f, &ipv4_short_key, p_key->l3_info.mpls.label[1].ttl);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsExp2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].exp);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsLabel2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].label);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsSbit2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].sbit);
        SetDsIpfixL3Ipv4ShortHashKey(V, uL3_gMpls_mplsTtl2_f, &ipv4_short_key, p_key->l3_info.mpls.label[2].ttl);
    }
    sal_memcpy((uint8*)p_data, (uint8*)&ipv4_short_key, sizeof(ipv4_short_key));
    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_encode_v6_short_key(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixL3Ipv6ShortHashKey_m ipv6_short_key;
    IpfixShortIpv6HashFieldSelect_m  hash_field;
    ipv6_addr_t hw_ip6;
    uint16 l4_srcport = 0;
    uint32 cmd = 0;
    ctc_ipfix_hash_field_sel_t field_sel;

    sal_memset(&ipv6_short_key, 0, sizeof(ipv6_short_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    sal_memset(&field_sel, 0, sizeof(field_sel));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6_SINGLE, &field_sel));
    if ((!(field_sel.u.ipv6.ipv6_low_en)) && ((field_sel.u.ipv6.ip_sa &&(p_key->l3_info.ipv6.ipsa_masklen > 64))
        || (field_sel.u.ipv6.ip_da &&(p_key->l3_info.ipv6.ipda_masklen > 64))))
    {
        return CTC_E_INVALID_PARAM;
    }
    if ((field_sel.u.ipv6.ipv6_low_en) && ((field_sel.u.ipv6.ip_sa &&(p_key->l3_info.ipv6.ipsa_masklen < 64))
        || (field_sel.u.ipv6.ip_da &&(p_key->l3_info.ipv6.ipda_masklen < 64))))
    {
        return CTC_E_INVALID_PARAM;
    }

    SetDsIpfixL3Ipv6ShortHashKey(V, hashKeyType0_f, &ipv6_short_key, SYS_IPFIX_HASH_TYPE_IPV6_SHORT);
    SetDsIpfixL3Ipv6ShortHashKey(V, hashKeyType1_f, &ipv6_short_key, SYS_IPFIX_HASH_TYPE_IPV6_SHORT);
    SetDsIpfixL3Ipv6ShortHashKey(V, flowFieldSel_f, &ipv6_short_key, p_key->field_sel_id);
    SetDsIpfixL3Ipv6ShortHashKey(V, ipfixCfgProfileId_f, &ipv6_short_key, p_key->profile_id);

    SetDsIpfixL3Ipv6ShortHashKey(V, ipfixHashSalt_f, &ipv6_short_key, p_key->hash_salt);
    if (field_sel.u.ipv6.fid)
    {
        SetDsIpfixL3Ipv6ShortHashKey(V, vsiId_f, &ipv6_short_key,  p_key->fid);
    }
    if (field_sel.u.ipv6.vrfid)
    {
        SetDsIpfixL3Ipv6ShortHashKey(V, vrfId_f, &ipv6_short_key,  p_key->l3_info.vrfid);
    }
    cmd =DRV_IOR(IpfixShortIpv6HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    SetDsIpfixL3Ipv6ShortHashKey(V, layer3HeaderProtocol_f, &ipv6_short_key, p_key->l4_info.type.ip_protocol);

    if ((!p_key->l4_info.type.ip_protocol || SYS_L4_PROTOCOL_IPV6_ICMP == p_key->l4_info.type.ip_protocol) && (field_sel.u.ipv6.icmp_code || field_sel.u.ipv6.icmp_type))
    {
        l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
        l4_srcport |= (((p_key->l4_info.icmp.icmp_type) & 0xff) << 8);
        SetDsIpfixL3Ipv6ShortHashKey(V, l4SourcePort_f, &ipv6_short_key, l4_srcport);
    }
    else if(field_sel.u.ipv6.igmp_type)
    {
        SetDsIpfixL3Ipv6ShortHashKey(V, l4SourcePort_f, &ipv6_short_key, (p_key->l4_info.igmp.igmp_type << 8));
    }
    else if((!p_key->l4_info.type.ip_protocol ||(SYS_L4_PROTOCOL_TCP == p_key->l4_info.type.ip_protocol|| SYS_L4_PROTOCOL_UDP ==p_key->l4_info.type.ip_protocol))
                && (field_sel.u.ipv6.l4_src_port || field_sel.u.ipv6.l4_dst_port))
    {
        SetDsIpfixL3Ipv6ShortHashKey(V, l4DestPort_f, &ipv6_short_key, p_key->l4_info.l4_port.dest_port);
        SetDsIpfixL3Ipv6ShortHashKey(V, l4SourcePort_f, &ipv6_short_key, p_key->l4_info.l4_port.source_port);
    }
    IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipsa, p_key->l3_info.ipv6.ipsa_masklen);
    IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipda, p_key->l3_info.ipv6.ipda_masklen);

    if (field_sel.u.ipv6.ip_da)
    {
        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipda);
        SetDsIpfixL3Ipv6ShortHashKey(A, ipDaPrefix_f, &ipv6_short_key, ((field_sel.u.ipv6.ipv6_low_en)?(&(hw_ip6[0])):(&(hw_ip6[2]))));
    }
    if (field_sel.u.ipv6.ip_sa)
    {
        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipsa);
        SetDsIpfixL3Ipv6ShortHashKey(A, ipSaPrefix_f, &ipv6_short_key, ((field_sel.u.ipv6.ipv6_low_en)?(&(hw_ip6[0])):(&(hw_ip6[2]))));
    }

    sal_memcpy((uint8*)p_data, (uint8*)&ipv6_short_key, sizeof(ipv6_short_key));
    return CTC_E_NONE;
}
#ifdef AT_TODO
STATIC int32
_sys_at_ipfix_encode_nsh_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixNshHashKey_m nsh_key;
    IpfixNshHashFieldSelect_m  hash_field;
    uint16 global_port = 0;
    ipv6_addr_t hw_ip6;
    uint16 l4_srcport = 0;
    uint32 cmd = 0;
    uint32 merge_data[2] = {0};
    ctc_ipfix_hash_field_sel_t field_sel;
    uint8 isipv4 = 0;/*tmp,nshhashselect*/
    uint8 isipv6 = 0;/*tmp,nshhashselect*/

    sal_memset(&nsh_key, 0, sizeof(nsh_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    sal_memset(&field_sel, 0, sizeof(field_sel));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel));/*tmp*/
    /* process gport, logic-port, metadata */

    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port, MCHIP_CAP(SYS_CAP_MAX_LOGIC_PORT));
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port,  0x7FFF);
        global_port = SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixNshHashKey(V, hashKeyType0_f, &nsh_key, SYS_IPFIX_HASH_TYPE_NSH);
    SetDsIpfixNshHashKey(V, hashKeyType1_f, &nsh_key, SYS_IPFIX_HASH_TYPE_NSH);
    SetDsIpfixNshHashKey(V, hashKeyType2_f, &nsh_key, SYS_IPFIX_HASH_TYPE_NSH);
    SetDsIpfixNshHashKey(V, hashKeyType3_f, &nsh_key, SYS_IPFIX_HASH_TYPE_NSH);
    SetDsIpfixNshHashKey(V, flowFieldSel_f, &nsh_key, p_key->field_sel_id);
    SetDsIpfixNshHashKey(V, globalPort_f, &nsh_key, global_port);
    SetDsIpfixNshHashKey(V, ipfixCfgProfileId_f, &nsh_key, p_key->profile_id);

    SetDsIpfixNshHashKey(V, vsiId_f, &nsh_key, p_key->fid);

    cmd =DRV_IOR(IpfixNshHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    SetDsIpfixNshHashKey(V, isMergeKey_f, &nsh_key, p_key->l4_info.aware_tunnel_info_en);
    SetDsIpfixNshHashKey(V, isVxlan_f, &nsh_key, (p_key->l4_info.aware_tunnel_info_en) ? 0 : (!!p_key->l4_info.vni));
    SetDsIpfixNshHashKey(V, layer3HeaderProtocol_f, &nsh_key, p_key->l4_info.type.ip_protocol);

    if (field_sel.u.ipv6.icmp_code || field_sel.u.ipv6.icmp_type)
    {
        l4_srcport = (p_key->l4_info.icmp.icmpcode) & 0xff;
        l4_srcport |= (((p_key->l4_info.icmp.icmp_type) & 0xff) << 8);
        SetDsIpfixNshHashKey(V, uL4_gPort_l4SourcePort_f, &nsh_key, l4_srcport);
    }
    else if(field_sel.u.ipv6.igmp_type)
    {
        SetDsIpfixNshHashKey(V, uL4_gPort_l4SourcePort_f, &nsh_key, (p_key->l4_info.igmp.igmp_type << 8));
    }
    else if(field_sel.u.ipv6.l4_src_port || field_sel.u.ipv6.l4_dst_port)
    {
        SetDsIpfixNshHashKey(V, uL4_gPort_l4DestPort_f, &nsh_key, p_key->l4_info.l4_port.dest_port);
        SetDsIpfixNshHashKey(V, uL4_gPort_l4SourcePort_f, &nsh_key, p_key->l4_info.l4_port.source_port);
    }

    if(!p_key->l4_info.aware_tunnel_info_en)
    {
        if (field_sel.u.ipv6.gre_key || field_sel.u.ipv6.nvgre_key)
        {
            SetDsIpfixNshHashKey(V, uL4_gKey_greKey_f, &nsh_key, p_key->l4_info.gre_key);
        }
        else if(field_sel.u.ipv6.vxlan_vni)
        {
            SetDsIpfixNshHashKey(V, uL4_gVxlan_vni_f, &nsh_key, p_key->l4_info.vni);
        }
    }
    SetDsIpfixNshHashKey(V, ipfixHashSalt_f, &nsh_key, p_key->hash_salt);
    if(field_sel.u.ipv6.fid)
    {
        SetDsIpfixNshHashKey(V, vsiId_f, &nsh_key,  p_key->fid);
    }

    if (isipv6) /*ipv6*/
    {
        IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipsa_masklen);
        IPFIX_IPV6_MASK_LEN_CHECK(p_key->l3_info.ipv6.ipda_masklen);

        IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipsa, p_key->l3_info.ipv6.ipsa_masklen);
        IPFIX_IPV6_MASK(p_key->l3_info.ipv6.ipda, p_key->l3_info.ipv6.ipda_masklen);

        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipda);
        SetDsIpfixNshHashKey(A, ipDa_f, &nsh_key, hw_ip6);

        IPFIX_SET_HW_IP6(hw_ip6, p_key->l3_info.ipv6.ipsa);
        SetDsIpfixNshHashKey(A, ipSa_f, &nsh_key, hw_ip6);
    }
    else if(isipv4)/*ipv4*/
    {
        IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipda_masklen);
        IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipda, p_key->l3_info.ipv4.ipda_masklen);
        SetDsIpfixL3Ipv4HashKey(V, ipDa_f, &nsh_key, p_key->l3_info.ipv4.ipda);

        IPFIX_IPV4_MASK_LEN_CHECK(p_key->l3_info.ipv4.ipsa_masklen);
        IPFIX_IPV4_MASK(p_key->l3_info.ipv4.ipsa, p_key->l3_info.ipv4.ipsa_masklen);
        SetDsIpfixL3Ipv4HashKey(V, ipSa_f, &nsh_key, p_key->l3_info.ipv4.ipsa);
    }

    if(p_key->l4_info.aware_tunnel_info_en)
    {
        SetDsIpfixNshHashKey(V, isMergeKey_f, &nsh_key, 1);
        if(field_sel.u.ipv6.vxlan_vni)
        {
            SetDsIpfixNshHashKey(V, mergeDataType_f, &nsh_key,SYS_IPFIX_MERGE_TYPE_VXLAN);
            merge_data[0] = p_key->l4_info.vni;
            SetDsIpfixNshHashKey(A, mergeData_f, &nsh_key, merge_data);
        }
        else if(field_sel.u.ipv6.gre_key || field_sel.u.ipv6.nvgre_key)
        {
            SetDsIpfixNshHashKey(V, mergeDataType_f, &nsh_key,SYS_IPFIX_MERGE_TYPE_GRE);
            merge_data[0] = p_key->l4_info.gre_key;
            SetDsIpfixNshHashKey(A, mergeData_f, &nsh_key, merge_data);
        }
    }
    if(field_sel.u.ipv6.src_cid)
    {
        SetDsIpfixNshHashKey(V, srcCategoryIdClassfied_f,&nsh_key, CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_SRC_CID_VALID));
        SetDsIpfixNshHashKey(V, srcCategoryId_f, &nsh_key,p_key->src_cid);
    }
    if(field_sel.u.ipv6.dst_cid)
    {
        SetDsIpfixNshHashKey(V, destCategoryIdClassfied_f,&nsh_key,CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_DST_CID_VALID));
        SetDsIpfixNshHashKey(V, destCategoryId_f, &nsh_key,p_key->dst_cid);
    }
    if(field_sel.u.ipv6.ecn)
    {
        SetDsIpfixNshHashKey(V, ecn_f, &nsh_key,p_key->l3_info.ipv6.ecn);
    }
    SetDsIpfixNshHashKey(V, tcpFlags_f, &nsh_key, (p_key->l4_info.tcp_flags));

    sal_memcpy((uint8*)p_data, (uint8*)&nsh_key, sizeof(nsh_key));
    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_encode_nsh_short_hashkey(uint8 lchip, ctc_ipfix_data_t* p_key, void* p_data)
{
    DsIpfixNshShortHashKey_m nsh_short_key;
    IpfixNshShortHashFieldSelect_m  hash_field;
    uint16 global_port = 0;
    uint32 cmd = 0;
    ctc_ipfix_hash_field_sel_t field_sel;

    sal_memset(&nsh_short_key, 0, sizeof(nsh_short_key));
    sal_memset(&hash_field, 0, sizeof(hash_field));
    sal_memset(&field_sel, 0, sizeof(field_sel));

    CTC_ERROR_RETURN(sys_usw_ipfix_get_hash_field_sel(lchip, p_key->field_sel_id, CTC_IPFIX_KEY_HASH_IPV6, &field_sel));/*tmp*/

    /* process gport, logic-port, metadata */
    if (p_key->port_type == CTC_IPFIX_PORT_TYPE_GPORT)
    {
        SYS_GLOBAL_PORT_CHECK(p_key->gport);
        global_port = SYS_MAP_CTC_GPORT_TO_DRV_GPORT(p_key->gport);
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_LOGIC_PORT)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port, MCHIP_CAP(SYS_CAP_MAX_LOGIC_PORT));
        global_port = p_key->logic_port;
    }
    else if(p_key->port_type == CTC_IPFIX_PORT_TYPE_METADATA)
    {
        CTC_MAX_VALUE_CHECK(p_key->logic_port,  0x7FFF);
        global_port = SYS_TMM_IPFIX_ENCODE_METADATA(p_key->logic_port);
    }

    SetDsIpfixNshShortHashKey(V, hashKeyType_f, &nsh_short_key, SYS_IPFIX_HASH_TYPE_NSH_SHORT);
    SetDsIpfixNshShortHashKey(V, flowFieldSel_f, &nsh_short_key, p_key->field_sel_id);
    SetDsIpfixNshShortHashKey(V, globalPort_f, &nsh_short_key, global_port);
    SetDsIpfixNshShortHashKey(V, ipfixCfgProfileId_f, &nsh_short_key, p_key->profile_id);
    SetDsIpfixNshShortHashKey(V, ipfixHashSalt_f, &nsh_short_key, p_key->hash_salt);

    cmd =DRV_IOR(IpfixNshShortHashFieldSelect0_t, DRV_ENTRY_FLAG);/*tmp*/
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_key->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    if(field_sel.u.ipv6.src_cid)/*tmp*/
    {
        SetDsIpfixNshShortHashKey(V, srcCategoryIdClassfied_f,&nsh_short_key, CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_SRC_CID_VALID));
        SetDsIpfixNshShortHashKey(V, srcCategoryId_f, &nsh_short_key,p_key->src_cid);
    }
    if(field_sel.u.ipv6.dst_cid)/*tmp*/
    {
        SetDsIpfixNshShortHashKey(V, destCategoryIdClassfied_f,&nsh_short_key,CTC_FLAG_ISSET(p_key->flags, CTC_IPFIX_DATA_DST_CID_VALID));
        SetDsIpfixNshShortHashKey(V, destCategoryId_f, &nsh_short_key,p_key->dst_cid);
    }

    sal_memcpy((uint8*)p_data, (uint8*)&nsh_short_key, sizeof(nsh_short_key));
    return CTC_E_NONE;
}
#endif

STATIC int32
_sys_at_ipfix_set_udf_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixUdfHashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint8 global_port_type = 0;
    uint32 hw_udf[8] = {0};
    sal_memset(&hash_field, 0, sizeof(IpfixUdfHashFieldSelect_m));
    SetIpfixUdfHashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);
    SetIpfixUdfHashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.udf.profile_id);
    SetIpfixUdfHashFieldSelect(V, udfHitIndexEn_f, &hash_field, 1);
    SetIpfixUdfHashFieldSelect(V, udfValidEn_f, &hash_field, field_sel->u.udf.udf_valid);

    SYS_USW_SET_HW_UDF(1, hw_udf, field_sel->u.udf.udf_data);
    SetIpfixUdfHashFieldSelect(A, udfDataEn_f, &hash_field, hw_udf);

    if(field_sel->u.udf.gport)
    {
        global_port_type = 1;
    }
    else if(field_sel->u.udf.logic_port)
    {
        global_port_type = 2;
    }
    else if(field_sel->u.udf.metadata)
    {
        global_port_type = 4;
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixUdfHashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);

    cmd = DRV_IOW(IpfixUdfHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW(IpfixUdfHashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_set_short_udf_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixUdfShortHashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint32 hw_udf[8] = {0};
    sal_memset(&hash_field, 0, sizeof(IpfixUdfShortHashFieldSelect_m));
    SetIpfixUdfShortHashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);
    SetIpfixUdfShortHashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.udf.profile_id);
    SetIpfixUdfShortHashFieldSelect(V, udfHitIndexEn_f, &hash_field, 1);
    SetIpfixUdfShortHashFieldSelect(V, udfValidEn_f, &hash_field, field_sel->u.udf.udf_valid);

    SYS_USW_SET_HW_UDF_SHORT(lchip, hw_udf, field_sel->u.udf.udf_data);
    SetIpfixUdfShortHashFieldSelect(A, udfDataEn_f, &hash_field, hw_udf);

    cmd = DRV_IOW(IpfixUdfShortHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW(IpfixUdfShortHashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}
#ifdef AT_TODO
STATIC int32
_sys_at_ipfix_set_nsh_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)/*need callback link*/
{
    IpfixNshHashFieldSelect_m hash_field;
    uint32 cmd = 0;
    uint32 ip_prefix_len = 0;
    uint8 global_port_type = 0;

    uint8 is_gre = !!field_sel->u.ipv6.gre_key;
    uint8 is_nvgre = !!field_sel->u.ipv6.nvgre_key;
    uint8 is_icmp = field_sel->u.ipv6.icmp_code || field_sel->u.ipv6.icmp_type;
    uint8 is_igmp = !!field_sel->u.ipv6.igmp_type;
    uint8 is_vxlan = !!field_sel->u.ipv6.vxlan_vni;
    uint8 is_l4_port = field_sel->u.ipv6.l4_src_port || field_sel->u.ipv6.l4_dst_port;

    if (field_sel->u.ipv6.aware_tunnel_info_en)
    {
        if ((is_gre + is_nvgre + is_vxlan ) > 1 )
        {
            return CTC_E_PARAM_CONFLICT;
        }

        if ((is_icmp + is_igmp + is_l4_port) > 1 )
        {
            return CTC_E_PARAM_CONFLICT;
        }
    }
    else if ((is_gre + is_nvgre + is_icmp + is_igmp + is_vxlan + is_l4_port) > 1 )
    {
        return CTC_E_PARAM_CONFLICT;
    }

    sal_memset(&hash_field, 0, sizeof(IpfixNshHashFieldSelect_m));

    SetIpfixNshHashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.ipv6.profile_id);/*tmp*/
    SetIpfixNshHashFieldSelect(V, icmpOpcodeEn_f, &hash_field, field_sel->u.ipv6.icmp_code);
    SetIpfixNshHashFieldSelect(V, icmpTypeEn_f, &hash_field, field_sel->u.ipv6.icmp_type);
    SetIpfixNshHashFieldSelect(V, igmpTypeEn_f, &hash_field, field_sel->u.ipv6.igmp_type);
    SetIpfixNshHashFieldSelect(V, l4DestPortEn_f, &hash_field, field_sel->u.ipv6.l4_dst_port);
    SetIpfixNshHashFieldSelect(V, l4SourcePortEn_f, &hash_field, field_sel->u.ipv6.l4_src_port);
    SetIpfixNshHashFieldSelect(V, layer3HeaderProtocolEn_f, &hash_field, field_sel->u.ipv6.ip_protocol);
    if(!field_sel->u.ipv6.aware_tunnel_info_en)
    {
        SetIpfixNshHashFieldSelect(V, greKeyEn_f, &hash_field, field_sel->u.ipv6.gre_key);
        SetIpfixNshHashFieldSelect(V, nvgreVsidEn_f, &hash_field, field_sel->u.ipv6.nvgre_key);
        SetIpfixNshHashFieldSelect(V, vxlanVniEn_f, &hash_field, field_sel->u.ipv6.vxlan_vni);
        SetIpfixNshHashFieldSelect(V, g1_mergeKeyMode_f, &hash_field, 0);
    }
    else
    {
        SetIpfixNshHashFieldSelect(V, g1_mergeKeyMode_f, &hash_field, 1);
        SetIpfixNshHashFieldSelect(V, g1_ignorVxlan_f, &hash_field, !(field_sel->u.ipv6.vxlan_vni));
        SetIpfixNshHashFieldSelect(V, g1_ignorGreWithKey_f, &hash_field, !(field_sel->u.ipv6.gre_key + field_sel->u.ipv6.nvgre_key));
        SetIpfixNshHashFieldSelect(V, g1_mergeKeyVxlanVniEn_f, &hash_field, field_sel->u.ipv6.vxlan_vni);
        SetIpfixNshHashFieldSelect(V, g1_mergeKeyNvgreVsidEn_f, &hash_field, field_sel->u.ipv6.nvgre_key);
        SetIpfixNshHashFieldSelect(V, g1_mergeKeyGreKeyEn_f, &hash_field, field_sel->u.ipv6.gre_key);
    }
    if (field_sel->u.ipv6.ip_da)
    {
        IPFIX_IPV6_MASK_LEN_CHECK(field_sel->u.ipv6.ip_da_mask);
        ip_prefix_len = (field_sel->u.ipv6.ip_da_mask>>2)-1;
        SetIpfixNshHashFieldSelect(V,  ipDaPrefixLengthForIpv6_f, &hash_field, ip_prefix_len);
        SetIpfixNshHashFieldSelect(V,  ipv6DaEn_f, &hash_field, 1);
    }

    if (field_sel->u.ipv6.ip_sa)
    {
        IPFIX_IPV6_MASK_LEN_CHECK(field_sel->u.ipv6.ip_sa_mask);
        ip_prefix_len = (field_sel->u.ipv6.ip_sa_mask>>2)-1;
        SetIpfixNshHashFieldSelect(V,  ipSaPrefixLengthForIpv6_f, &hash_field, ip_prefix_len);
        SetIpfixNshHashFieldSelect(V,  ipv6SaEn_f, &hash_field, 1);
    }

    if (field_sel->u.ipv4.ip_da)
    {
        IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.ipv4.ip_da_mask);
        ip_prefix_len = field_sel->u.ipv4.ip_da_mask - 1 ;
        SetIpfixNshHashFieldSelect(V,  ipDaPrefixLengthForIpv4_f, &hash_field, ip_prefix_len);
        SetIpfixNshHashFieldSelect(V,  ipv4DaEn_f, &hash_field, 1);
    }

    if (field_sel->u.ipv4.ip_sa)
    {
        IPFIX_IPV4_MASK_LEN_CHECK(field_sel->u.ipv4.ip_sa_mask);
        ip_prefix_len = field_sel->u.ipv4.ip_sa_mask - 1;
        SetIpfixNshHashFieldSelect(V,  ipSaPrefixLengthForIpv4_f, &hash_field, ip_prefix_len);
        SetIpfixNshHashFieldSelect(V,  ipv4SaEn_f, &hash_field, 1);
    }

    SetIpfixNshHashFieldSelect(V, g1_srcCategoryIdEn_f, &hash_field, field_sel->u.ipv6.src_cid);
    SetIpfixNshHashFieldSelect(V, g1_dstCategoryIdEn_f, &hash_field, field_sel->u.ipv6.dst_cid);
    SetIpfixNshHashFieldSelect(V, g1_ecnEn_f, &hash_field, field_sel->u.ipv6.ecn);
    SetIpfixNshHashFieldSelect(V, g1_tcpFlagsEn_f, &hash_field, field_sel->u.ipv6.tcp_flags);

    SetIpfixNshHashFieldSelect(V, vsiIdEn_f, &hash_field, field_sel->u.ipv6.fid);
    SetIpfixNshHashFieldSelect(V, tcpBidiFlowSessionEn_f, &hash_field, field_sel->u.ipv6.sym_session_en);
    SetIpfixNshHashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);

    if(field_sel->u.ipv6.gport)
    {
        global_port_type = 1;
    }
    else if(field_sel->u.ipv6.logic_port)
    {
        global_port_type = 2;
    }
    else if(field_sel->u.ipv6.metadata)
    {
         global_port_type = 4;
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixNshHashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);

    cmd = DRV_IOW( IpfixNshHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixNshHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW( IpfixNshHashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    return CTC_E_NONE;
}

 STATIC int32
_sys_at_ipfix_set_nsh_short_hash_sel(uint8 lchip, ctc_ipfix_hash_field_sel_t* field_sel)/*need callback link*/
{
    IpfixNshShortHashFieldSelect_m  hash_field;
    uint32 cmd = 0;
    uint8 global_port_type = 0;

    sal_memset(&hash_field, 0, sizeof(IpfixNshShortHashFieldSelect_m));

    if(field_sel->u.ipv6.gport)
    {
        global_port_type = 1;
    }
    else if(field_sel->u.ipv6.logic_port)
    {
        global_port_type = 2;
    }
    else if(field_sel->u.ipv6.metadata)
    {
        global_port_type = 4;
    }
    else
    {
        global_port_type = 0;
    }
    SetIpfixNshShortHashFieldSelect(V, globalPortType_f, &hash_field, global_port_type);
    SetIpfixNshShortHashFieldSelect(V, ipfixHashSaltEn_f, &hash_field, 1);
    SetIpfixNshShortHashFieldSelect(V, ipfixCfgProfileIdEn_f, &hash_field, field_sel->u.ipv6.profile_id);
    SetIpfixNshShortHashFieldSelect(V, srcCategoryIdEn_f, &hash_field, field_sel->u.ipv6.src_cid);
    SetIpfixNshShortHashFieldSelect(V, dstCategoryIdEn_f, &hash_field, field_sel->u.ipv6.dst_cid);
    SetIpfixNshShortHashFieldSelect(V, tcpBidiFlowSessionEn_f, &hash_field, field_sel->u.ipv6.sym_session_en);

    cmd = DRV_IOW(IpfixNshShortHashFieldSelect_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW(IpfixNshShortHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));
    cmd = DRV_IOW(IpfixNshShortHashFieldSelect1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel->field_sel_id, DRV_CMD_PP_EN(cmd), &hash_field));

    return CTC_E_NONE;
}
#endif

STATIC int32
_sys_at_ipfix_get_v4_short_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixShortIpv4HashFieldSelect_m v4_short_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR(IpfixShortIpv4HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v4_short_hash_field));
    field_sel->u.ipv4.profile_id = GetIpfixShortIpv4HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.ip_da = GetIpfixShortIpv4HashFieldSelect(V,  ipDaEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.ip_da_mask = field_sel->u.ipv4.ip_da ? (GetIpfixShortIpv4HashFieldSelect(V,  ipDaPrefixLength_f, &v4_short_hash_field) + 1) : 0;
    field_sel->u.ipv4.ip_sa = GetIpfixShortIpv4HashFieldSelect(V,  ipSaEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.ip_sa_mask = field_sel->u.ipv4.ip_sa ? (GetIpfixShortIpv4HashFieldSelect(V,  ipSaPrefixLength_f, &v4_short_hash_field)  + 1) : 0;
    field_sel->u.ipv4.ip_protocol = GetIpfixShortIpv4HashFieldSelect(V, layer3HeaderProtocolEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.l4_dst_port = GetIpfixShortIpv4HashFieldSelect(V, l4DestPortEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.l4_src_port = GetIpfixShortIpv4HashFieldSelect(V, l4SourcePortEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.icmp_code = GetIpfixShortIpv4HashFieldSelect(V, icmpOpcodeEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.icmp_type = GetIpfixShortIpv4HashFieldSelect(V, icmpTypeEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.igmp_type = GetIpfixShortIpv4HashFieldSelect(V, igmpTypeEn_f, &v4_short_hash_field);
    field_sel->u.ipv4.sym_session_en = GetIpfixShortIpv4HashFieldSelect(V, tcpBidiFlowSessionEn_f, &v4_short_hash_field);
    if (GetIpfixShortIpv4HashFieldSelect(V, flexDataType_f, &v4_short_hash_field) == 0x1)
    {
        field_sel->u.ipv4.gport = 1;
    }
    else if (GetIpfixShortIpv4HashFieldSelect(V, flexDataType_f, &v4_short_hash_field) == 0x7)
    {
        field_sel->u.ipv4.fid = 1;
    }
    else if ((GetIpfixShortIpv4HashFieldSelect(V, flexDataType_f, &v4_short_hash_field) > 0x2) && \
        (GetIpfixShortIpv4HashFieldSelect(V, flexDataType_f,  &v4_short_hash_field) < 0x7))
    {
        field_sel->u.ipv4.vrfid = 1;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_get_v6_short_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixShortIpv6HashFieldSelect_m v6_short_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR(IpfixShortIpv6HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v6_short_hash_field));
    field_sel->u.ipv6.ip_da = GetIpfixShortIpv6HashFieldSelect(V,  ipDaEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.ip_da_mask = field_sel->u.ipv6.ip_da ? ((GetIpfixShortIpv6HashFieldSelect(V, ipDaPrefixLength_f, &v6_short_hash_field) + 1) << 2) : 0;
    field_sel->u.ipv6.ip_sa = GetIpfixShortIpv6HashFieldSelect(V,  ipSaEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.ip_sa_mask = field_sel->u.ipv6.ip_sa ? ((GetIpfixShortIpv6HashFieldSelect(V, ipSaPrefixLength_f, &v6_short_hash_field) + 1) << 2) : 0;
    field_sel->u.ipv6.ip_protocol = GetIpfixShortIpv6HashFieldSelect(V, layer3HeaderProtocolEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.l4_dst_port = GetIpfixShortIpv6HashFieldSelect(V, l4DestPortEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.l4_src_port = GetIpfixShortIpv6HashFieldSelect(V, l4SourcePortEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.icmp_code = GetIpfixShortIpv6HashFieldSelect(V, icmpOpcodeEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.icmp_type = GetIpfixShortIpv6HashFieldSelect(V, icmpTypeEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.igmp_type = GetIpfixShortIpv6HashFieldSelect(V, igmpTypeEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.sym_session_en = GetIpfixShortIpv6HashFieldSelect(V, tcpBidiFlowSessionEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.profile_id = GetIpfixShortIpv6HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.ipv6_low_en = GetIpfixShortIpv6HashFieldSelect(V, ipSelLowEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.fid = GetIpfixShortIpv6HashFieldSelect(V, vsiIdEn_f, &v6_short_hash_field);
    field_sel->u.ipv6.vrfid = GetIpfixShortIpv6HashFieldSelect(V, vrfIdEn_f, &v6_short_hash_field);
    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_get_mpls_short_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixShortIpv4HashFieldSelect_m v4_short_hash_field;
    uint32 cmd = 0;

    cmd = DRV_IOR(IpfixShortIpv4HashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &v4_short_hash_field));
    field_sel->u.mpls.profile_id = GetIpfixShortIpv4HashFieldSelect(V, ipfixCfgProfileIdEn_f, &v4_short_hash_field) ;
    field_sel->u.mpls.label_num = GetIpfixShortIpv4HashFieldSelect(V,  labelNumEn_f, &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label0_exp = GetIpfixShortIpv4HashFieldSelect(V,  mplsExp0En_f, &v4_short_hash_field);
    field_sel->u.mpls.mpls_label1_exp = GetIpfixShortIpv4HashFieldSelect(V,  mplsExp1En_f, &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label2_exp = GetIpfixShortIpv4HashFieldSelect(V,  mplsExp2En_f, &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label0_label = GetIpfixShortIpv4HashFieldSelect(V, mplsLabel0En_f    , &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label1_label = GetIpfixShortIpv4HashFieldSelect(V, mplsLabel1En_f    , &v4_short_hash_field);
    field_sel->u.mpls.mpls_label2_label = GetIpfixShortIpv4HashFieldSelect(V, mplsLabel2En_f    , &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label0_s = GetIpfixShortIpv4HashFieldSelect(V, mplsSbit0En_f     , &v4_short_hash_field);
    field_sel->u.mpls.mpls_label1_s = GetIpfixShortIpv4HashFieldSelect(V, mplsSbit1En_f     , &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label2_s = GetIpfixShortIpv4HashFieldSelect(V, mplsSbit2En_f     , &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label0_ttl = GetIpfixShortIpv4HashFieldSelect(V, mplsTtl0En_f      , &v4_short_hash_field);
    field_sel->u.mpls.mpls_label1_ttl = GetIpfixShortIpv4HashFieldSelect(V, mplsTtl1En_f      , &v4_short_hash_field) ;
    field_sel->u.mpls.mpls_label2_ttl = GetIpfixShortIpv4HashFieldSelect(V, mplsTtl2En_f      , &v4_short_hash_field) ;
    return CTC_E_NONE;
}

STATIC int32
_sys_at_ipfix_get_udf_hash_sel(uint8 lchip, uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixUdfHashFieldSelect_m  udf_hash_field;
    uint32 cmd = 0;
    uint32 hw_udf[4] = {0};

    cmd = DRV_IOR(IpfixUdfHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &udf_hash_field));
    field_sel->u.udf.profile_id = GetIpfixUdfHashFieldSelect(V, ipfixCfgProfileIdEn_f, &udf_hash_field);
    field_sel->u.udf.udf_valid = GetIpfixUdfHashFieldSelect(V, udfValidEn_f, &udf_hash_field);
    GetIpfixUdfHashFieldSelect(A, udfDataEn_f, &udf_hash_field, hw_udf);
    SYS_USW_SET_USR_UDF(1,  field_sel->u.udf.udf_data, hw_udf);

    switch (GetIpfixUdfHashFieldSelect(V, globalPortType_f, &udf_hash_field))
    {
        case 1:
            field_sel->u.udf.gport = 1;
            break;
        case 2:
            field_sel->u.udf.logic_port = 1;
            break;
        case 3:
        case 4:
            field_sel->u.udf.metadata = 1;
            break;
        default:
            break;
    }
    return CTC_E_NONE;
}


STATIC int32
_sys_at_ipfix_get_udf_short_hash_sel(uint8 lchip,uint8 field_sel_id, ctc_ipfix_hash_field_sel_t* field_sel)
{
    IpfixUdfHashFieldSelect_m  udf_hash_field;
    uint32 cmd = 0;
    uint32 hw_udf[4] = {0};

    cmd = DRV_IOR(IpfixUdfShortHashFieldSelect0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_sel_id, DRV_CMD_PP_EN(cmd), &udf_hash_field));
    field_sel->u.udf.profile_id = GetIpfixUdfShortHashFieldSelect(V, ipfixCfgProfileIdEn_f, &udf_hash_field);
    field_sel->u.udf.udf_valid = GetIpfixUdfShortHashFieldSelect(V, udfValidEn_f, &udf_hash_field);
    GetIpfixUdfShortHashFieldSelect(A, udfDataEn_f, &udf_hash_field, hw_udf);
    SYS_USW_SET_USR_UDF_SHORT(lchip,  field_sel->u.udf.udf_data, hw_udf);
    return CTC_E_NONE;
}

int32
sys_at_ipfix_encode_ad(uint8 lchip, sys_ipfix_param_t* param)
{
    DsIpfixSessionRecord_m ad_rec;
    uint32 dest_type = SYS_IPFIX_UNICAST_DEST;
    uint32 dest_chip_id = 0;
    uint32 lport = 0;
    uint32 byte_cnt[2] = {0};
    ctc_ipfix_data_t* p_key = param -> p_key;

    sal_memset(&ad_rec, 0, sizeof(ad_rec));

    lport = SYS_MAP_CTC_GPORT_TO_DRV_LPORT(p_key->dest_gport);
    dest_chip_id = SYS_MAP_CTC_GPORT_TO_GCHIP(p_key->dest_gport);
    if (p_key->flags & CTC_IPFIX_DATA_L2_MCAST_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uModule_g1_destinationInfo_f , &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_L2MC_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_L3_MCAST_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uModule_g1_destinationInfo_f , &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_L3MC_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_BCAST_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uModule_g1_destinationInfo_f, &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_BCAST_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_APS_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uModule_g1_destinationInfo_f, &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_APS_DEST;
    }
    if (p_key->flags & CTC_IPFIX_DATA_ECMP_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uModule_g1_destinationInfo_f, &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_ECMP_DEST;
    }

    if (p_key->flags & CTC_IPFIX_DATA_LINKAGG_DETECTED)
    {
        SetDsIpfixSessionRecord(V, uModule_g1_destinationInfo_f, &ad_rec, p_key->dest_group_id);
        dest_type = SYS_IPFIX_LAG_DEST;
    }
    else
    {
        SetDsIpfixSessionRecord(V, uModule_g1_destinationInfo_f, &ad_rec, dest_chip_id<<9 | lport);
    }

    byte_cnt[0] = (uint32)p_key->byte_count;
    byte_cnt[1] = (uint32)(p_key->byte_count >> 32);
    SetDsIpfixSessionRecord(V, exportReason_f, &ad_rec, p_key->export_reason);
    SetDsIpfixSessionRecord(V, expired_f, &ad_rec, (p_key->export_reason==CTC_IPFIX_REASON_EXPIRED)?1:0);
    SetDsIpfixSessionRecord(V, uModule_g1_destinationType_f, &ad_rec, dest_type);
    SetDsIpfixSessionRecord(A, byteCount_f, &ad_rec, byte_cnt);
    SetDsIpfixSessionRecord(V, packetCount_f, &ad_rec, p_key->pkt_count);
    SetDsIpfixSessionRecord(V, fragment_f , &ad_rec, (p_key->flags&CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED)?1:0);
    SetDsIpfixSessionRecord(V, uModule_g1_minTtl_f, &ad_rec, p_key->min_ttl);
    SetDsIpfixSessionRecord(V, uModule_g1_maxTtl_f, &ad_rec, p_key->max_ttl);
    SetDsIpfixSessionRecord(V, nonFragment_f, &ad_rec, (p_key->flags&CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED)? 0 : 1);
    SetDsIpfixSessionRecord(V, tcpFlagsStatus_f, &ad_rec, p_key->tcp_flags);
    SetDsIpfixSessionRecord(V, valid_f, &ad_rec, 1);
    sal_memcpy((uint8*)(&param->igr_ad_data), (uint8*)&ad_rec,sizeof(ad_rec));
    return CTC_E_NONE;
}
int32
sys_at_ipfix_decode_mmu_ad(uint8 lchip, void* data, void* p_ad)
{
    ctc_ipfix_data_t* p_data = (ctc_ipfix_data_t*)data;
    sys_at_ipfix_mmu_record_decode_t* p_ad_s = (sys_at_ipfix_mmu_record_decode_t*)p_ad;
    uint16 reason_bmp = 0;
    uint16 chan_id;
    uint16 lport = 0;
    uint8 gchip = 0;
    chan_id = p_ad_s->destChannelId_0_7 | (p_ad_s->destChannelId_8_8<<8);
    lport = sys_usw_port_api_get_lport_with_chan(lchip, 0, chan_id);
    CTC_ERROR_RETURN(drv_get_gchip_id(lchip, &gchip));
    p_data->dest_port = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
    p_data->burst_state = p_ad_s->burstState;
    p_data->queue_id = p_ad_s->queueOffset;
    p_data->queue_count = p_ad_s->curQueueCnt;
    p_data->min_queue_count = p_ad_s->minQueueCnt;
    p_data->max_queue_count = p_ad_s->maxQueueCnt_0_3 | (p_ad_s->maxQueueCnt_4_17<<4);
    reason_bmp = p_ad_s->discardVec;
    _sys_usw_ipfix_map_mmu_reason_sys_to_ctc_bmp(lchip, reason_bmp, p_data, 0);
    reason_bmp = (p_ad_s->discardVec1_0_6|(p_ad_s->discardVec1_7_10<<7));
    _sys_usw_ipfix_map_mmu_reason_sys_to_ctc_bmp(lchip, reason_bmp, p_data, 1);
    p_data->buf_drop_cnt = p_ad_s->discardCnt;

    return CTC_E_NONE;
}

int32
sys_at_ipfix_decode_ad(uint8 lchip, void* data, void* p_ad)
{
    uint32 dest_type = 0;
    uint8 dest_chip = 0;
    uint32 drop_class_vector = 0;
    uint32 cmd = 0;
    ctc_ipfix_data_t* p_data = (ctc_ipfix_data_t*)data;
    sys_at_ipfix_record_decode_t* p_ad_s = (sys_at_ipfix_record_decode_t*)p_ad;
    sys_ipfix_xalu_vec_t* xalu_type_vec = NULL;
    uint32 xalu_ad_data[CTC_IPFIX_FLOW_TRACK_MAX];
    DsIpfixConfig1_m ipfix_cfg;
    uint32 alu_profile_tbl_idx = 0;
    uint32 is_32bit = 0;
    uint8 alu_en = 0;
    uint8 alu_type = 0;
    
    sal_memset(xalu_ad_data,0,sizeof(xalu_ad_data));
    p_data->pkt_count = p_ad_s->packetCount_0_24 | (p_ad_s->packetCount_25_29<<25);
    p_data->byte_count = p_ad_s->byteCount_0_26 | ((uint64)p_ad_s->byteCount_27_35<<27);
    p_data->tcp_flags = p_ad_s->tcpFlagsStatus;
    if (p_ad_s->fragment)
    {
        p_data->flags |= CTC_IPFIX_DATA_FRAGMENT_PKT_DETECTED;
    }

    if (0 == p_ad_s->uDiscardInfoType)/* g1 */
    {
        p_data->drop_pkt_cnt[0] = (p_ad_s->uDiscardInfo_ >>6)&0x3FF;
        p_data->drop_pkt_cnt[1] = p_ad_s->uDiscardInfo_ >>22;
        p_data->drop_reason[0] = p_ad_s->uDiscardInfo_&0x3F;
        p_data->drop_reason[1] = (p_ad_s->uDiscardInfo_>>16)&0x3F;
        if (p_data->drop_pkt_cnt[0] || p_data->drop_pkt_cnt[1])
        {
            p_data->flags |= CTC_IPFIX_DATA_DROP_DETECTED;

        }
    }
    else /* g2 */
    {
        drop_class_vector = p_ad_s->uDiscardInfo_;
        sys_tmm_ipfix_drop_clalssid_to_reason(lchip, drop_class_vector, p_data->drop_reason_bmp, p_data->dir);
        if(p_data->e_drop_reason_bmp[0] || p_data->e_drop_reason_bmp[1] || p_data->e_drop_reason[0] || p_data->e_drop_reason[1])
        {
            p_data->flags |= CTC_IPFIX_DATA_DROP_DETECTED;
        }

    }

    if (p_ad_s->uModuleType == 2)/*for ALU*/
    {
        xalu_type_vec = ctc_vector_get(p_usw_ipfix_master[lchip]->xalu_vec, p_data->profile_id);
        if(!xalu_type_vec)
        {
            CTC_ERROR_RETURN(CTC_E_NOT_EXIST);
        }
        cmd = DRV_IOR(DsIpfixConfig1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_data->profile_id, DRV_CMD_PP_EN(cmd), &ipfix_cfg));
        alu_en =  GetDsIpfixConfig(V, aluEn_f, &ipfix_cfg);
        while(alu_en)
        {
            if(alu_en & 0x1)
            {
                is_32bit = (alu_profile_tbl_idx < SYS_ALU_USE_32BITWISE)?(xalu_type_vec->xalu_type[alu_profile_tbl_idx] >> 7):0;
                alu_type = (xalu_type_vec->xalu_type[alu_profile_tbl_idx] & 0x7f);

                xalu_ad_data[alu_type] =*(&p_ad_s->uModule__0_31+alu_profile_tbl_idx % 4);
                xalu_ad_data[alu_type] = (alu_profile_tbl_idx/4)?(xalu_ad_data[alu_type]>>16):
                    ((is_32bit)?xalu_ad_data[alu_type]:xalu_ad_data[alu_type]&0xffff);
            }
            alu_en = alu_en>>1;
            alu_profile_tbl_idx++;
        }
        p_data->burst_cnt = xalu_ad_data[CTC_IPFIX_FLOW_TRACK_BURST_EVENT];
        p_data->latency_cnt = xalu_ad_data[CTC_IPFIX_FLOW_TRACK_LATENCY_EVENT];
        p_data->max_latency = xalu_ad_data[CTC_IPFIX_FLOW_TRACK_MAX_LATENCY];
        p_data->min_latency = xalu_ad_data[CTC_IPFIX_FLOW_TRACK_MIN_LATENCY];
        p_data->avg_latency = xalu_ad_data[CTC_IPFIX_FLOW_TRACK_AVG_LATENCY];
        p_data->last_timestamp = xalu_ad_data[CTC_IPFIX_FLOW_TRACK_TS];
    }
    else
    {
        if (p_data->dir == CTC_EGRESS && (p_ad_s->uModuleType == 1))
        {
            p_data->max_latency = ((p_ad_s->uModule__64_95>>16) | ((p_ad_s->uModule__96_127&0xFF)<<16))<<5;
            p_data->min_latency = (p_ad_s->uModule__96_127>>8)<<5;
            p_data->avg_latency = (p_ad_s->uModule__32_63>>24 | ((p_ad_s->uModule__64_95&0xFFFF)<<8))<<5;
            p_data->max_jitter = (p_ad_s->uModule__0_31>>16)<<5;
            p_data->avg_jitter = (p_ad_s->uModule__0_31&0xFFFF)<<5;
            p_data->last_latency = (p_ad_s->uModule__32_63&0xFFFFFF)<<5;
        }
        else
        {
            dest_type = (p_ad_s->uModule__64_95>>22)&0xF;
            p_data->last_ttl = (p_ad_s->uModule__32_63>>12)&0xFF;
            p_data->max_ttl = (p_ad_s->uModule__32_63>>20)&0xFF;
            p_data->min_ttl = p_ad_s->uModule__32_63>>28 | (p_ad_s->uModule__64_95&0xF)<<4;
            p_data->start_timestamp = p_ad_s->uModule__0_31>>22 | (p_ad_s->uModule__32_63&0xFFF)<<10;
            p_data->last_timestamp = p_ad_s->uModule__0_31&0x3FFFFF;
            if (p_data->last_timestamp < p_data->start_timestamp)
            {
                p_data->last_timestamp |= 0x400000;
            }
            switch (dest_type)
            {
                case SYS_IPFIX_UNICAST_DEST:
                    dest_chip = (p_ad_s->uModule__64_95>>13)&0x7F;
                    p_data->dest_gport = (p_ad_s->uModule__64_95>>4)&0x1FF;
                    p_data->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip,  p_data->dest_gport);
                    break;
                case SYS_IPFIX_L2MC_DEST:
                    p_data->dest_group_id = (p_ad_s->uModule__64_95>>4)&0x3FFFF;
                    p_data->flags |= CTC_IPFIX_DATA_L2_MCAST_DETECTED;
                    break;
                case SYS_IPFIX_L3MC_DEST:
                    p_data->dest_group_id = (p_ad_s->uModule__64_95>>4)&0x3FFFF;
                    p_data->flags |= CTC_IPFIX_DATA_L3_MCAST_DETECTED;
                    break;
                case SYS_IPFIX_BCAST_DEST:
                    p_data->dest_group_id = (p_ad_s->uModule__64_95>>4)&0x3FFFF;
                    p_data->flags |= CTC_IPFIX_DATA_BCAST_DETECTED;
                    break;
                case SYS_IPFIX_UNKNOW_PKT_DEST:
                    p_data->dest_group_id = (p_ad_s->uModule__64_95>>4)&0x3FFFF;
                    p_data->flags |= CTC_IPFIX_DATA_UNKNOW_PKT_DETECTED;
                    break;
                case SYS_IPFIX_UNION_DEST:
                    p_data->dest_group_id = (p_ad_s->uModule__64_95>>4)&0xFFF;
                    p_data->flags |= CTC_IPFIX_DATA_APS_DETECTED;
                    break;
                    #if 0
                case 8:
                    dest_chip = GetDsIpfixSessionFullRecord0(V, uDestinationInfo_gUcastToNormal_destChipId_f , p_ad);
                    p_data->dest_gport = GetDsIpfixSessionFullRecord0(V, uDestinationInfo_gUcastToNormal_destId_f , p_ad);
                    p_data->dest_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(dest_chip, p_data->dest_gport);
                    p_data->flags |= CTC_IPFIX_DATA_ECMP_DETECTED;
                    break;
                    #endif
                case SYS_IPFIX_LAG_DEST:
                    p_data->dest_group_id = (p_ad_s->uModule__64_95>>4)&0x3FFFF;
                    p_data->flags |= CTC_IPFIX_DATA_LINKAGG_DETECTED;
                    break;
                case SYS_IPFIX_CPU_DEST:
                    p_data->dest_gport = (1 << CTC_TYPE_PORT_OFFSET | \
                    ((p_ad_s->uModule__64_95>>13)&0x7F) << CTC_LOCAL_PORT_LENGTH);
                    break;
                case 15:
                    p_data->dest_group_id = (p_ad_s->uModule__64_95>>4)&0xFFF;
                    if (p_data->dest_group_id)
                    {
                        p_data->flags |= CTC_IPFIX_DATA_L2_MCAST_DETECTED;
                    }
                    break;
                default:
                    return CTC_E_INVALID_PARAM;
            }
        }
    }
    return CTC_E_NONE;
}

int32
_sys_at_ipfix_xkey_vector(void* array_data, uint32 index, void* user_data)
{
    sys_ipfix_flexed_key_t *p_ipfix = (sys_ipfix_flexed_key_t *)array_data;
    sys_ipfix_flexed_key_t *data = (sys_ipfix_flexed_key_t *)user_data;
    if ((data->key_type == p_ipfix->origin_key_type) && (data->dir == p_ipfix->dir))
    {
        data->key_type = p_ipfix->key_type;
        data->mode = p_ipfix->mode;
    }

    return CTC_E_NONE;
}


int32
sys_at_ipfix_decode_key_ad(uint8 lchip, ctc_ipfix_data_t* p_data, uint8 is_ad, void* p_key)
{
    uint8 hash_key_valid = 0;
    DsIpfixL3Ipv6HashKey_m* hash_key = (DsIpfixL3Ipv6HashKey_m*)p_key;
    uint8 hash_key_type = 0;
    uint8 origin_key_type = 0;
    sys_ipfix_flexed_key_t xkey_user_data;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&xkey_user_data, 0, sizeof(sys_ipfix_flexed_key_t));
    if (is_ad == 1)
    {
        sys_at_ipfix_decode_ad(lchip, p_data, p_key);
    }
    else if (is_ad == 2)
    {
        sys_at_ipfix_decode_mmu_ad(lchip, p_data, p_key);
    }
    else
    {

        hash_key_type = GetDsIpfixL3Ipv6HashKey(V, hashKeyType0_f, hash_key);
        origin_key_type = ctc_at_hash_type[hash_key_type&0xF];
        hash_key_valid = GetDsIpfixL3Ipv6HashKey(V, xKeyValid0_f, hash_key);

        if (hash_key_valid && origin_key_type == CTC_IPFIX_KEY_HASH_IPV4_SINGLE)
        {
            xkey_user_data.dir = p_data->dir;
            xkey_user_data.key_type = origin_key_type;
            CTC_ERROR_RETURN(ctc_vector_traverse2(p_usw_ipfix_master[lchip]->flex_key_vec,CTC_IPFIX_KEY_HASH_FLEX_BASE,
            _sys_at_ipfix_xkey_vector, (void *)&xkey_user_data));
        }
        if (xkey_user_data.mode != CTC_FIELD_FLEX_KEY_MODE_REPLACE)
        {
            CTC_ERROR_RETURN(p_usw_ipfix_master[lchip]->callbacks_decode[origin_key_type](lchip, p_data, p_key));
        }
        if(hash_key_valid)
        {
            CTC_ERROR_RETURN(_sys_at_ipfix_decode_flex_key(lchip, p_data, p_key));
        }
    }
    return CTC_E_NONE;
}
#define ___IPFIX_FLEX_KEY_START___

int32
_sys_at_ipfix_set_xkey_valid(uint8 lchip, void* ipfix_flex_key, void* key_param)
{
    sys_ipfix_flexed_key_t* p_flexed_key = (sys_ipfix_flexed_key_t*)(ipfix_flex_key);
    sys_ipfix_param_t* pkey = (sys_ipfix_param_t*)key_param;
    uint8 drv_key_type = 0;
    drv_key_type = sys_at_hash_type[p_flexed_key->origin_key_type];

    if(p_flexed_key->key_size == SYS_IPFIX_SINGLE_KEY_SIZE)
    {
        SetDsIpfixXKeySingleHashKey(V,xKeyValid_f, pkey->key_data,1);
        SetDsIpfixXKeySingleHashKey(V,hashKeyType_f, pkey->key_data,drv_key_type);
    }
    else if(p_flexed_key->key_size == SYS_IPFIX_DOUBLE_KEY_SIZE)
    {
        SetDsIpfixXKeyDoubleHashKey(V,xKeyValid0_f, pkey->key_data,1);
        SetDsIpfixXKeyDoubleHashKey(V,hashKeyType0_f, pkey->key_data,drv_key_type);
        SetDsIpfixXKeyDoubleHashKey(V,xKeyValid1_f, pkey->key_data,1);
        SetDsIpfixXKeyDoubleHashKey(V,hashKeyType1_f, pkey->key_data,drv_key_type);
    }
    else if(p_flexed_key->key_size == SYS_IPFIX_QUAD_KEY_SIZE)
    {
        SetDsIpfixXKeyQuadHashKey(V,xKeyValid0_f, pkey->key_data,1);
        SetDsIpfixXKeyQuadHashKey(V,hashKeyType0_f, pkey->key_data,drv_key_type);
        SetDsIpfixXKeyQuadHashKey(V,xKeyValid1_f, pkey->key_data,1);
        SetDsIpfixXKeyQuadHashKey(V,hashKeyType1_f, pkey->key_data,drv_key_type);
        SetDsIpfixXKeyQuadHashKey(V,xKeyValid2_f, pkey->key_data,1);
        SetDsIpfixXKeyQuadHashKey(V,hashKeyType2_f, pkey->key_data,drv_key_type);
        SetDsIpfixXKeyQuadHashKey(V,xKeyValid3_f, pkey->key_data,1);
        SetDsIpfixXKeyQuadHashKey(V,hashKeyType3_f, pkey->key_data,drv_key_type);
    }

    return CTC_E_NONE;
}

int32
sys_at_ipfix_get_flex_key_sets(uint8 lchip, void* ipfix_flex_key)
{
    ctc_ipfix_flex_key_t * p_ipfix_flex_key = NULL;
    ctc_ipfix_kset_t kset_base;
    ctc_xdata_local_type_t type;
    sys_xdata_fk_t p_fk;
    uint32 key_tbl_id = 0;

    p_ipfix_flex_key = (ctc_ipfix_flex_key_t*)ipfix_flex_key;
    sal_memset(&kset_base, 0 , sizeof(kset_base));
    sal_memset(&p_fk, 0 , sizeof(sys_xdata_fk_t));
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_VALUE_RANGE_CHECK(p_ipfix_flex_key->mode, CTC_FIELD_FLEX_KEY_MODE_APPEND, CTC_FIELD_FLEX_KEY_MODE_MAX-1);
    CTC_MAX_VALUE_CHECK(p_ipfix_flex_key->origin_key_type, CTC_IPFIX_KEY_HASH_FLEX_BASE-1);
    if((p_ipfix_flex_key->origin_key_type == CTC_IPFIX_KEY_HASH_UDF || p_ipfix_flex_key->origin_key_type == CTC_IPFIX_KEY_HASH_UDF_SINGLE)&&
        p_ipfix_flex_key->dir == CTC_EGRESS)
    {
        return CTC_E_NOT_SUPPORT;
    }
    type = p_ipfix_flex_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
    sys_usw_xdata_local_get_kset(lchip, type, &kset_base);
    
    sal_memcpy(p_ipfix_flex_key->kset.w, &kset_base.w,sizeof(uint32)*CTC_B2W_SIZE(CTC_FIELD_KEY_NUM));

    p_fk.mode = p_ipfix_flex_key->mode-1;
    p_fk.hash_type = 0;
    p_fk.type = type;
    key_tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_ipfix_flex_key->origin_key_type,p_ipfix_flex_key->dir);
    p_fk.tbl_id = SYS_IPFIX_GET_TABLE(key_tbl_id, p_ipfix_flex_key->dir);
    if (MCHIP_XDATA(lchip)->fk_get_flex_bits)
    {
        CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->fk_get_flex_bits(lchip, &p_fk));
    }
    p_ipfix_flex_key->flex_bits = p_fk.flex_bits;
    return CTC_E_NONE;
}

int32
sys_at_ipfix_get_flex_key(uint8 lchip, void* ipfix_flex_key)
{
    ctc_ipfix_flex_key_t * p_ipfix_flex_key = NULL;
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;
    sys_xdata_fk_t p_fk;
    uint32 key_tbl_id = 0;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&p_fk, 0 , sizeof(sys_xdata_fk_t));
    p_ipfix_flex_key = (ctc_ipfix_flex_key_t*)ipfix_flex_key;
    CTC_VALUE_RANGE_CHECK(p_ipfix_flex_key->key_type, CTC_IPFIX_KEY_HASH_FLEX_BASE, CTC_IPFIX_KEY_HASH_FLEX_END);
    CTC_VALUE_RANGE_CHECK(p_ipfix_flex_key->mode, CTC_FIELD_FLEX_KEY_MODE_APPEND, CTC_FIELD_FLEX_KEY_MODE_MAX-1);

    p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (p_ipfix_flex_key->key_type | (p_ipfix_flex_key->dir<<7)));
    if (NULL == p_flexed_key)
    {
        return CTC_E_NOT_EXIST;
    }
    sal_memcpy(p_ipfix_flex_key->kset.w, p_flexed_key->kset.w,sizeof(uint32)*CTC_B2W_SIZE(CTC_FIELD_KEY_NUM));
    p_ipfix_flex_key->dir = p_flexed_key->dir;
    p_ipfix_flex_key->origin_key_type = p_flexed_key->origin_key_type;
    p_fk.mode = p_ipfix_flex_key->mode-1;
    p_fk.hash_type = 0;
    p_fk.type = p_ipfix_flex_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
    key_tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_ipfix_flex_key->origin_key_type, p_ipfix_flex_key->dir);
    p_fk.tbl_id = SYS_IPFIX_GET_TABLE(key_tbl_id, p_ipfix_flex_key->dir);
    if (MCHIP_XDATA(lchip)->fk_get_flex_bits)
    {
        CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->fk_get_flex_bits(lchip, &p_fk));
    }
    p_ipfix_flex_key->flex_bits = p_fk.flex_bits;

   return CTC_E_NONE;
}

int32
_sys_at_ipfix_decode_flex_key(uint8 lchip, void* pdata, void* key)
{
    ctc_ipfix_data_t* data = (ctc_ipfix_data_t*) pdata;
    uint32 loop = 0;
    sys_xdata_fk_io_t xdata_fk;
    ctc_field_key_t* pKey = data->flex_key.field_list;
    uint32* hash_key = (uint32*)key;
    uint32 key_tbl_id;
    int32 ret;
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;
    uint32 tmp_key_type;
    uint32 gchip = 0;
    uint32 lport = 0;
    ctc_xdata_t* pxdata = &(data->xdata);
    sal_memset(&xdata_fk,0, sizeof(sys_xdata_fk_io_t));
    if (data->key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
    {
        tmp_key_type = data->key_type;
    }
    else
    {
        p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (data->key_type | (data->dir << 7)));
        if (!p_flexed_key)
        {
            return CTC_E_NOT_EXIST;
        }
        tmp_key_type = p_flexed_key->origin_key_type;
    }
    key_tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(tmp_key_type,data->dir);
    key_tbl_id = SYS_IPFIX_GET_TABLE(key_tbl_id, data->dir);
    xdata_fk.tbl_id = key_tbl_id;
    xdata_fk.type = data->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;

    for (loop = 0; loop < CTC_FIELD_KEY_NUM; loop++)
    {
        switch(loop)
        {
            case CTC_FIELD_KEY_SRC_GPORT:
                xdata_fk.fk_field = SYS_FK_F_SRC_GPORT;
                SYS_GET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
                if(!ret)
                {
                    pKey->type = loop;
                    gchip = SYS_DECODE_DESTMAP_GCHIP(pKey->data);
                    lport = SYS_DECODE_DESTMAP_LPORT(pKey->data);
                    pKey->data = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip,lport);
                    data->flex_key.field_num++;
                    pKey++;
                }
                break;
            case CTC_FIELD_KEY_IP_TTL:
                xdata_fk.fk_field = SYS_FK_F_PR_IP_TTL;
                SYS_GET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
                if(!ret)
                {
                    pKey->type = loop;
                    data->flex_key.field_num++;
                    pKey++;
                }
                break;
            case CTC_FIELD_KEY_DISCARD:
                xdata_fk.fk_field = SYS_FK_F_DISCARD;
                SYS_GET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
                xdata_fk.fk_field = SYS_FK_F_DISCARD_TYPE;
                SYS_GET_IPFIX_FK_FIELD(xdata_fk, pKey->mask);
                if(!ret)
                {
                    pKey->type = loop;
                    data->flex_key.field_num++;
                    pKey++;

                }
                break;
            case CTC_FIELD_KEY_PRIORITY:
                xdata_fk.fk_field = SYS_FK_F_PRIORITY;
                SYS_GET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
                if(!ret)
                {
                    pKey->type = loop;
                    data->flex_key.field_num++;
                    pKey++;

                }
                break;
            case CTC_FIELD_KEY_XDATA:
                xdata_fk.fk_field = SYS_FK_F_XDATA;
                xdata_fk.xdata = pxdata;
                xdata_fk.xdata->type = data->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
                SYS_GET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
                
                break;
            default:
                break;
        }
    }
    return CTC_E_NONE;
}

int32
_sys_at_ipfix_build_xdata_field(uint8 lchip,void* ipfix_flex_key, void* key_param)
{
    sys_ipfix_flexed_key_t* p_flexed_key = (sys_ipfix_flexed_key_t*)ipfix_flex_key;
    sys_ipfix_param_t * p_param = (sys_ipfix_param_t*)key_param;
    uint32 key_tbl_id;
    sys_xdata_fk_io_t xdata_fk;
    ctc_xdata_t* pxdata = &(p_param->p_key->xdata);
    uint32* hash_key = NULL;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&xdata_fk,0, sizeof(sys_xdata_fk_io_t));
    hash_key = (uint32*)(p_param->key_data);
    key_tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_flexed_key->origin_key_type,p_flexed_key->dir);
    key_tbl_id = SYS_IPFIX_GET_TABLE(key_tbl_id, p_flexed_key->dir);
    xdata_fk.type = p_param->p_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
    xdata_fk.tbl_id = key_tbl_id;
    xdata_fk.fk_field = SYS_FK_F_XDATA;
    xdata_fk.xdata = pxdata;
    xdata_fk.xdata->type = p_param->p_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
    SYS_SET_IPFIX_FK_FIELD(xdata_fk, 1);
    return CTC_E_NONE;
}

int32
_sys_at_ipfix_build_flex_key_field(uint8 lchip, void* ipfix_flex_key, void* key_param, void* field_list)
{
    sys_ipfix_flexed_key_t* p_flexed_key = (sys_ipfix_flexed_key_t*)ipfix_flex_key;
    sys_ipfix_param_t * flex_key_param = (sys_ipfix_param_t*)key_param;
    ctc_field_key_t*pKey = (ctc_field_key_t*)field_list;
    uint32 key_tbl_id;
    sys_xdata_fk_io_t xdata_fk;
    uint32* hash_key = NULL;
    uint32 gchip = 0;
    uint32 lport = 0;
    uint32 data = 0;
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(pKey);
    CTC_PTR_VALID_CHECK(flex_key_param);

    hash_key = (uint32*)(flex_key_param->key_data);
    key_tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_flexed_key->origin_key_type,p_flexed_key->dir);
    key_tbl_id = SYS_IPFIX_GET_TABLE(key_tbl_id, p_flexed_key->dir);
    xdata_fk.tbl_id = key_tbl_id;
    xdata_fk.type = flex_key_param->p_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
    switch(pKey->type)
    {
         case CTC_FIELD_KEY_SRC_GPORT:
            gchip = CTC_MAP_GPORT_TO_GCHIP(pKey->data);
            lport = CTC_MAP_GPORT_TO_LPORT(pKey->data);
            data = SYS_ENCODE_DESTMAP(gchip,lport);
            xdata_fk.fk_field = SYS_FK_F_SRC_GPORT;
            SYS_SET_IPFIX_FK_FIELD(xdata_fk, data);
            break;
         case CTC_FIELD_KEY_IP_TTL:
            CTC_MAX_VALUE_CHECK(pKey->data, CTC_CONST256-1);
            xdata_fk.fk_field = SYS_FK_F_PR_IP_TTL;
            SYS_SET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
            break;
         case CTC_FIELD_KEY_DISCARD:
            CTC_MAX_VALUE_CHECK(pKey->mask, CTC_CONST32-1);
            xdata_fk.fk_field = SYS_FK_F_DISCARD;
            SYS_SET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
            xdata_fk.fk_field = SYS_FK_F_DISCARD_TYPE;
            SYS_SET_IPFIX_FK_FIELD(xdata_fk, pKey->mask);
            break;
         case CTC_FIELD_KEY_PRIORITY:
            CTC_MAX_VALUE_CHECK(pKey->data, CTC_CONST16-1);
            xdata_fk.fk_field = SYS_FK_F_PRIORITY;
            SYS_SET_IPFIX_FK_FIELD(xdata_fk, pKey->data);
            break;
         default:
            SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " API or some feature is not supported \n");
            return CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}
int32
sys_at_ipfix_encode_xkey_hash(uint8 lchip, void* param)
{
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;
    uint32 tmp_count = 0;
    sys_ipfix_param_t* p_param = (sys_ipfix_param_t*)param;
    ctc_field_key_t* new_field_list = (ctc_field_key_t*)p_param->p_key->flex_key.field_list;
    ctc_field_key_t* p_field_list = (ctc_field_key_t*)p_param->p_key->flex_key.field_list;
    ctc_ipfix_kset_t p_kset;
    uint32 loop = 0;
    
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (p_param->p_key->key_type | (p_param->p_key->dir<<7)));
    if (!p_flexed_key)
    {
        return CTC_E_NOT_EXIST;
    }

    /*1.check, add flex key field must be in before-set software table*/
    sal_memcpy(&p_kset,&(p_flexed_key->kset),sizeof(ctc_ipfix_kset_t));
    tmp_count = p_param->p_key->flex_key.field_num;
    while(tmp_count)
    {
        if (CTC_BMP_ISSET(p_kset.w, new_field_list->type))
        {
            CTC_BMP_UNSET(p_kset.w, new_field_list->type);
            tmp_count --;
            new_field_list++;
        }
        else
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    if (p_param->p_key->xdata.num)
    {
        if (CTC_BMP_ISSET(p_kset.w, CTC_FIELD_KEY_XDATA))
        {
            CTC_BMP_UNSET(p_kset.w, CTC_FIELD_KEY_XDATA);
        }
    }
    for (loop = 0; loop < CTC_B2W_SIZE(CTC_FIELD_KEY_NUM); loop++)
    {
        if(p_kset.w[loop] != 0)
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    /*2.encode origin*/
    if (p_flexed_key->mode != CTC_FIELD_FLEX_KEY_MODE_REPLACE)
    {
        p_param->p_key->key_type = p_flexed_key->origin_key_type;
        CTC_ERROR_RETURN(_sys_usw_ipfix_encode_hash(lchip, p_param));/*encode origin hash*/
    }
    p_param->p_key->key_type = p_flexed_key->key_type;
    /*3.encode flex key local field*/
    tmp_count = p_param->p_key->flex_key.field_num;
    while(tmp_count)
    {
        tmp_count --;
        CTC_ERROR_RETURN(_sys_at_ipfix_build_flex_key_field(lchip, p_flexed_key, p_param,p_field_list));
        p_field_list++;
    }
    /*4.encode flex key xdata field*/
    if(p_param->p_key->xdata.num)
    {
        CTC_ERROR_RETURN(_sys_at_ipfix_build_xdata_field(lchip, p_flexed_key, p_param));
    }
    /*5.set valid*/
    CTC_ERROR_RETURN(_sys_at_ipfix_set_xkey_valid(lchip,p_flexed_key, p_param));
    return CTC_E_NONE;
}

int32
_sys_at_ipfix_map_xkey_field_type(uint8 lchip, uint16 field_type, uint8* p_fk_field_type,ctc_ipfix_flex_key_t* ipfix_flex_key, uint8* num)
{
    uint8 field_num = 0;
    uint8 loop = 0;
    switch(field_type)
    {
        case CTC_FIELD_KEY_SRC_GPORT:
            *p_fk_field_type = SYS_FK_F_SRC_GPORT;
            field_num = 1;
            break;
        case CTC_FIELD_KEY_IP_TTL:
            *p_fk_field_type = SYS_FK_F_PR_IP_TTL;
            field_num = 1;
            break;
        case CTC_FIELD_KEY_DISCARD:
            *p_fk_field_type = SYS_FK_F_DISCARD;
            *(p_fk_field_type + 1) = SYS_FK_F_DISCARD_TYPE;
            field_num = 2;
            break;
        case CTC_FIELD_KEY_PRIORITY:
            *p_fk_field_type = SYS_FK_F_PRIORITY;
            field_num = 1;
            break;
        case CTC_FIELD_KEY_XDATA:
            for(loop= 0; loop < ipfix_flex_key->xdata->num; loop++)
            {
                *(p_fk_field_type+loop) = SYS_FK_F_XDATA;
            }
            field_num = ipfix_flex_key->xdata->num;
            break;

        default:
            return CTC_E_INVALID_PARAM;
    }
    if (num)
    {
        *num = field_num;
    }
    return CTC_E_NONE;
}

int32
_sys_at_ipfix_set_flex_key(uint8 lchip, sys_xdata_fk_t* p_fk, ctc_ipfix_flex_key_t* ipfix_flex_key)
{
    int32 ret = CTC_E_NONE;
    uint16 i;
    uint8 j;
    uint8 xpi_field_num = 0;
    uint8 fk_field[SYS_IPFIX_FK_FIELD_NUM] = {0};
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    for(i = 0; i < CTC_FIELD_KEY_NUM; i++)
    {
        if(!CTC_BMP_ISSET(ipfix_flex_key->kset.w, i))
        {
            continue;
        }
        sal_memset(&p_fk->info,0,sizeof(sys_xdata_fk_field_t));
        if (_sys_at_ipfix_map_xkey_field_type(lchip, i, fk_field, ipfix_flex_key, &xpi_field_num))/*ctc mapping sys xone field*/
        {
            continue;
        }
        p_fk->info.ptr_field_name = ifp_field_str[i];
        if(0 == xpi_field_num)
        {
            CTC_ERROR_GOTO(CTC_E_INVALID_PARAM, ret, error0);
        }
        for (j = 0; j < xpi_field_num; j++)
        {
            p_fk->info.field = fk_field[j];
            if (CTC_FIELD_KEY_XDATA == i)
            {
                p_fk->info.src_pos = ipfix_flex_key->xdata->fields[j].offset/CTC_XDATA_WIDTH_4;
                p_fk->info.width = ipfix_flex_key->xdata->fields[j].width;
                p_fk->info.mask = ipfix_flex_key->xdata->fields[j].mask;
            }
            CTC_ERROR_GOTO(MCHIP_XDATA(lchip)->add_fk(lchip, p_fk), ret, error0);/*according to the key type,try xdata_fk field*/
        }
    }
    sal_memset(&p_fk->info,0,sizeof(sys_xdata_fk_field_t));
    p_fk->info.field = SYS_FK_F_FIELD_DONE;
    p_fk->info.ptr_field_name = "done";
    CTC_ERROR_GOTO(MCHIP_XDATA(lchip)->add_fk(lchip, p_fk), ret, error0);
    return CTC_E_NONE;
error0:
    if(ret != CTC_E_ENTRY_EXIST)
    {
        MCHIP_XDATA(lchip)->remove_fk(lchip, p_fk);
    }

    return ret;
}

int32
_sys_at_ipfix_array_is_empty(uint8* array, uint32 len)
{
    uint32 loop = 0;
    do
    {
        if (array[loop++] != 0)
        {
            return FALSE;
        }
    }while(loop<len);
    return TRUE;
}

int32
sys_at_ipfix_set_flex_key(uint8 lchip, void* ipfix_flex_key)
{
    int32 ret = CTC_E_NONE;
    uint8  kset_is_empty = FALSE;
    ctc_ipfix_flex_key_t * p_ipfix_flex_key = (ctc_ipfix_flex_key_t*)ipfix_flex_key;
    sys_ipfix_flexed_key_t* p_flexed_key = NULL;/*old vector flex key*/
    sys_ipfix_flexed_key_t* fixed_key_new;/*new vector flex key*/
    sys_xdata_fk_t xdata_fk;
    uint32 key_tbl_id;
    uint32 entry_size = 0;
    ctc_ipfix_kset_t* p_kset = NULL;/*origin kset*/
    ctc_ipfix_kset_t kset_tmp;
    uint32 loop = 0;
    sys_ipfix_flexed_key_t xkey_user_data;/*pegging the flex key type*/
    ctc_xdata_field_t* p_field = NULL;
    ctc_ipfix_kset_t kset_base;
    uint32 type = 0;
    
    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    /*1.check the valid range*/
    CTC_VALUE_RANGE_CHECK(p_ipfix_flex_key->key_type | (p_ipfix_flex_key->dir<<7), CTC_IPFIX_KEY_HASH_FLEX_BASE, CTC_IPFIX_KEY_HASH_FLEX_END);
    CTC_MAX_VALUE_CHECK(p_ipfix_flex_key->origin_key_type, CTC_IPFIX_KEY_HASH_FLEX_BASE-1);
    if((p_ipfix_flex_key->origin_key_type == CTC_IPFIX_KEY_HASH_UDF || p_ipfix_flex_key->origin_key_type == CTC_IPFIX_KEY_HASH_UDF_SINGLE) && p_ipfix_flex_key->dir)
    {
        return CTC_E_NOT_SUPPORT;
    }
    sal_memset(&kset_tmp, 0, sizeof(ctc_ipfix_kset_t));
    sal_memset(&xdata_fk, 0, sizeof(sys_xdata_fk_t));
    /*check flex key has exited*/
    kset_is_empty = _sys_at_ipfix_array_is_empty((uint8*)p_ipfix_flex_key->kset.w, CTC_B2W_SIZE(CTC_FIELD_KEY_NUM)*sizeof(uint32));
    p_flexed_key = ctc_vector_get(p_usw_ipfix_master[lchip]->flex_key_vec, (p_ipfix_flex_key->key_type | (p_ipfix_flex_key->dir<<7)));/*vector 7bit storage dir*/
    /*pegging and checking the flex key type*/
    xkey_user_data.key_type = p_ipfix_flex_key->origin_key_type;
    xkey_user_data.dir = p_ipfix_flex_key->dir;
    CTC_ERROR_RETURN(ctc_vector_traverse2(p_usw_ipfix_master[lchip]->flex_key_vec,CTC_IPFIX_KEY_HASH_FLEX_BASE,
                    _sys_at_ipfix_xkey_vector, (void *)&xkey_user_data));
    if(xkey_user_data.key_type >= CTC_IPFIX_KEY_HASH_FLEX_BASE && !kset_is_empty)
    {
        return CTC_E_EXIST;
    }
    if (!kset_is_empty && NULL != p_flexed_key)
    {   /*not support update*/
        return CTC_E_EXIST;
    }
    else if (kset_is_empty && NULL == p_flexed_key)
    {   /*both NULL and do nothing*/
        return CTC_E_NONE;
    }
    else if (kset_is_empty && NULL != p_flexed_key && p_ipfix_flex_key->dir == p_flexed_key->dir)
    {   /*kset is empty,so delete the flex key*/
        key_tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_ipfix_flex_key->origin_key_type,p_ipfix_flex_key->dir);
        key_tbl_id = SYS_IPFIX_GET_TABLE(key_tbl_id, p_ipfix_flex_key->dir);
        xdata_fk.tbl_id = key_tbl_id;
        xdata_fk.type = p_ipfix_flex_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
        MCHIP_XDATA(lchip)->remove_fk(lchip, &xdata_fk);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XKEY_VEC, 1);
        ctc_vector_del(p_usw_ipfix_master[lchip]->flex_key_vec, (p_ipfix_flex_key->key_type | (p_ipfix_flex_key->dir<<7)));
        mem_free(p_flexed_key);
        return CTC_E_NONE;
    }
    /*unique */
    CTC_VALUE_RANGE_CHECK(p_ipfix_flex_key->mode, CTC_FIELD_FLEX_KEY_MODE_APPEND, CTC_FIELD_FLEX_KEY_MODE_MAX-1);
    p_kset = (ctc_ipfix_kset_t*)(p_usw_ipfix_master[lchip]->kset_db[p_ipfix_flex_key->dir][CTC_IPFIX_KEY_HASH_FLEX_BASE]);
    if (NULL == p_kset)
    {
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Invalid key type, key_type:%u!\n", CTC_IPFIX_KEY_HASH_FLEX_BASE);
        return CTC_E_NOT_SUPPORT;
    }
    type = p_ipfix_flex_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
    sys_usw_xdata_local_get_kset(lchip, type, &kset_base);
    
    for (loop = 0; loop < CTC_B2W_SIZE(CTC_FIELD_KEY_NUM); loop++)
    {
        kset_tmp.w[loop] = p_kset->w[loop] | p_ipfix_flex_key->kset.w[loop];
        if((p_kset->w[loop] != kset_tmp.w[loop]) || (kset_base.w[loop] != (kset_base.w[loop]|p_ipfix_flex_key->kset.w[loop])))
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    if(CTC_BMP_ISSET(p_ipfix_flex_key->kset.w, CTC_FIELD_KEY_XDATA))
    {
        for(loop = 0; loop < p_ipfix_flex_key->xdata->num; loop++)
        {
            p_field = &p_ipfix_flex_key->xdata->fields[loop];
            switch(p_field->width)
            {
                case CTC_XDATA_WIDTH_4:
                case CTC_XDATA_WIDTH_8:
                case CTC_XDATA_WIDTH_16:
                    if((0 != p_field->offset % p_field->width)||(CTC_CONST128 < p_field->offset + p_field->width))
                    {
                        return CTC_E_INVALID_PARAM;
                    }
                break;
                default:
                    return CTC_E_INVALID_PARAM;
            }
        }
    }
    key_tbl_id = SYS_IPFIX_GET_TAB_BY_TYPE(p_ipfix_flex_key->origin_key_type,p_ipfix_flex_key->dir);
    key_tbl_id = SYS_IPFIX_GET_TABLE(key_tbl_id, p_ipfix_flex_key->dir);
    CTC_ERROR_RETURN(sys_usw_ftm_query_table_entry_size(lchip, key_tbl_id, &entry_size));

    xdata_fk.tbl_id = key_tbl_id;
    xdata_fk.hash_type= 0;
    xdata_fk.type = p_ipfix_flex_key->dir ? CTC_XDATA_LOCAL_TYPE_EGS_IPFIX: CTC_XDATA_LOCAL_TYPE_IPFIX;
    xdata_fk.mode = p_ipfix_flex_key->mode-1;
    if (MCHIP_XDATA(lchip)->fk_get_flex_bits)
    {
        CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->fk_get_flex_bits(lchip, &xdata_fk));
    }
    if (!xdata_fk.flex_bits)
    {
        return CTC_E_NOT_SUPPORT;
    }
    CTC_ERROR_RETURN(_sys_at_ipfix_set_flex_key(lchip, &xdata_fk, p_ipfix_flex_key));

    MALLOC_ZERO(MEM_IPFIX_MODULE, fixed_key_new, sizeof(sys_ipfix_flexed_key_t));
    if (!fixed_key_new)
    {
        goto error1;
    }
    fixed_key_new->key_type = p_ipfix_flex_key->key_type;
    fixed_key_new->origin_key_type = p_ipfix_flex_key->origin_key_type;
    fixed_key_new->dir = p_ipfix_flex_key->dir;
    fixed_key_new->key_size = (p_ipfix_flex_key->mode == CTC_FIELD_FLEX_KEY_MODE_DOUBLE_APPEND)? entry_size*2 : entry_size;
    fixed_key_new->mode = p_ipfix_flex_key->mode;
    sal_memcpy(&(fixed_key_new->kset), &(p_ipfix_flex_key->kset),sizeof(ctc_ipfix_kset_t));
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_IPFIX, SYS_WB_APPID_IPFIX_SUBID_XKEY_VEC, 1);
    if (FALSE == ctc_vector_add(p_usw_ipfix_master[lchip]->flex_key_vec, (p_ipfix_flex_key->key_type | (p_ipfix_flex_key->dir<<7)), fixed_key_new))
    {
        ret = CTC_E_NO_MEMORY;
        SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [ipfix] Hash insert fail\n");
        goto error2;
    }

    return CTC_E_NONE;
error2:
    mem_free(fixed_key_new);
error1:
    MCHIP_XDATA(lchip)->remove_fk(lchip, &xdata_fk);
    return ret;
}

#define ___IPFIX_FLEX_KEY_END___

#define IPFIX_KEY_DMA_WORD                             32
#define IPFIX_AD_DMA_WORD                              16
int32
sys_at_ipfix_traverse_dma(uint8 lchip, void* cb, void* data, uint8 is_remove)
{
    int32 ret = 0;
    uint32 index = 0;
    uint32 count = 0;
    void* p_key = NULL;
    void* p_ad = NULL;
    void* p_buffer = NULL;
    void* p_buffer_ad = NULL;
    uint32 cfg_addr = 0;
    uint32 cfg_ad_addr = 0;
    uint32 cmdr_flow_cnt = 0;
    uint32 cmdr_ad = 0;
    ctc_ipfix_data_t ipfix_data;
    uint32 ipfix_max_entry_num = 0;
    uint32 dump_end_entry_num = 0;
    uint32 ipfix_entry_num = 0;
    uint32 next_index = 0;
    uint16 traverse_action = 0;
    uint8 sub_idx = 0;
    uint8 hash_type[4] = {0};
    uint32 temp_idx;
    sys_dma_tbl_rw_t dma_rw;
    drv_work_platform_type_t platform_type;
    uint32 entry_cnt = 0;
    uint32 loop = 0;
    uint32 key_index = 0;
    uint8 dir = 0;
    uint16 buff_size = 512;
    uint8 key_width = 0;
    uint8 idx_left = 0;
    uint32 use_io = 0;
    ctc_ipfix_traverse_t* p_data = (ctc_ipfix_traverse_t*)data;
    ctc_ipfix_traverse_t dump_info;
    ctc_ipfix_traverse_fn fn = cb;
    IpfixFlowEntryCounter_m flow_cnt;
    uint8 ad_size= TABLE_ENTRY_SIZE(lchip,DsIpfixSessionRecord_t)/4;
    uint8 xKeyValid[4] = {0};
    sys_ipfix_flexed_key_t xkey_user_data;

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&flow_cnt, 0, sizeof(flow_cnt));
    sal_memset(&dump_info, 0, sizeof(dump_info));
    sal_memset(&xkey_user_data, 0, sizeof(sys_ipfix_flexed_key_t));
    if(p_data->user_data != NULL)
    {
        traverse_action = *(uint16*)p_data->user_data;
    }

    sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));
    MALLOC_ZERO(MEM_IPFIX_MODULE, p_buffer, buff_size*sizeof(DsIpfixL3Ipv6HashKey_m));
    if (NULL == p_buffer)
    {
        return CTC_E_NO_MEMORY;
    }
    MALLOC_ZERO(MEM_IPFIX_MODULE, p_buffer_ad, buff_size*4*sizeof(DsIpfixSessionRecord_m));
    if (NULL == p_buffer_ad)
    {
        mem_free(p_buffer);
        return CTC_E_NO_MEMORY;
    }
    CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsIpfixL3Ipv4ShortHashKey_t, &ipfix_entry_num), ret, end_pro);/* get 120bits bits entry num */

    /* 1. p_data->start_index: based 120bit;
    2. 4 aligned processed by DMA, and use p_buffer for DMA, so the start index should be aligned ahead.
    3. e.g. start index 21,22,23, index is 20, idx_left is 1,2,3
    4. DMA process based on 480bit;    */
    ipfix_max_entry_num =  ipfix_entry_num*2; /*Ingress + Egress*/
    if (p_data->start_index < ipfix_entry_num )
    {
        dir = CTC_INGRESS;
        dump_end_entry_num = ipfix_entry_num; /*ingress*/
    }
    else
    {
        dir = CTC_EGRESS;
        dump_end_entry_num = ipfix_max_entry_num;
    }

    cmdr_flow_cnt = DRV_IOR(dir? IpfixFlowEntryCounter1_t : IpfixFlowEntryCounter0_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmdr_flow_cnt), &flow_cnt);
    if(GetIpfixFlowEntryCounter(V, flowEntryCount_f, &flow_cnt) < SYS_IPFIX_DUMP_FLOW_CNT)
    {
        use_io = 1;
    }
    idx_left = p_data->start_index % 4;
    if (idx_left)
    {
        index = (p_data->start_index / 4)*4;
    }
    else
    {
        index = p_data->start_index;
    }

    SYS_IPFIX_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "ipfix_max_entry_num = %d\n", ipfix_max_entry_num);

    if(index >= ipfix_max_entry_num)
    {
        goto end_pro;
    }
    if (index >= dump_end_entry_num && dir == CTC_INGRESS)
    {
        next_index = dump_end_entry_num;
        goto end_pro;
    }
    sal_memset(&dma_rw, 0, sizeof(dma_rw));
    do
    {
        /*Notice: start_index and next_traverse_index is 120bits encoding index, for dma performance, every
        Dma operation is by 480bits */
        entry_cnt = ((index + buff_size*4) <= dump_end_entry_num)? buff_size : ((dump_end_entry_num - index) / 4);
        drv_get_platform_type(lchip, &platform_type);
        key_index = index;
          if (platform_type == HW_PLATFORM)
        {
            CTC_ERROR_GOTO(drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, SYS_IPFIX_GET_TABLE(DsIpfixL3Ipv6HashKey_t, dir), (dir? (key_index - ipfix_entry_num) : key_index), &cfg_addr), ret, end_pro);
            CTC_ERROR_GOTO(drv_get_table_property(lchip, DRV_TABLE_PROP_HW_ADDR, SYS_IPFIX_GET_TABLE(DsIpfixSessionRecord_t,dir), SYS_IPFIX_GET_ADINDEX(index, dir), &cfg_ad_addr), ret, end_pro);
        }
        else
        {
            /*special process for uml*/
            cfg_addr = (SYS_IPFIX_GET_TABLE(DsIpfixL3Ipv6HashKey_t, dir) << 18)|(dir? (key_index - ipfix_entry_num) : key_index);
            cfg_ad_addr = (SYS_IPFIX_GET_TABLE(DsIpfixSessionRecord_t,dir) << 18)| (SYS_IPFIX_GET_ADINDEX(index, dir));
        }

        dma_rw.tbl_addr = cfg_addr;
        dma_rw.entry_num = entry_cnt;
        dma_rw.entry_len = TABLE_ENTRY_SIZE(lchip, DsIpfixL3Ipv6HashKey_t);
        dma_rw.op_bmp = SYS_USW_DMA_ENCODE_OP_BMP(lchip, MEM_TYPE_PER_PP, lchip - (SYS_PP_BASE(lchip)), 0);
        dma_rw.buffer = p_buffer;
        dma_rw.entry_offset = IPFIX_KEY_DMA_WORD << 2;
        CTC_ERROR_GOTO(MCHIP_DMA(lchip)->dma_read_table(SYS_PP_BASE(lchip), &dma_rw), ret, end_pro);

        if(0 ==use_io)
        {
            dma_rw.tbl_addr = cfg_ad_addr;
            dma_rw.entry_num = 4*entry_cnt;
            dma_rw.entry_len = 4*ad_size;
            dma_rw.buffer = p_buffer_ad;
            dma_rw.op_bmp = SYS_USW_DMA_ENCODE_OP_BMP(lchip, MEM_TYPE_PER_PP, lchip - (SYS_PP_BASE(lchip)), 0);
            dma_rw.entry_offset = IPFIX_AD_DMA_WORD << 2;
            CTC_ERROR_GOTO(MCHIP_DMA(lchip)->dma_read_table(SYS_PP_BASE(lchip), &dma_rw), ret, end_pro);
        }

        for(loop=0; loop < entry_cnt; loop++)
        {
            p_key = (DsIpfixL3Ipv6HashKey_m*)((uint8*)p_buffer + loop*TABLE_ENTRY_SIZE(lchip, DsIpfixL3Ipv6HashKey_t));
            if(0 == use_io)
            {
                p_ad = (uint32*)p_buffer_ad + 4*loop*ad_size;
            }
            hash_type[0] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType0_f, p_key);
            hash_type[1] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType1_f, p_key);
            hash_type[2] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType2_f, p_key);
            hash_type[3] = GetDsIpfixL3Ipv6HashKey(V, hashKeyType3_f, p_key);
            if ((hash_type[0] + hash_type[1] + hash_type[2] + hash_type[3]) == SYS_IPFIX_HASH_TYPE_INVALID)
            {
                idx_left = 0;
                continue;
            }
            xKeyValid[0] = GetDsIpfixL3Ipv6HashKey(V, xKeyValid0_f, p_key);
            xKeyValid[1] = GetDsIpfixL3Ipv6HashKey(V, xKeyValid1_f, p_key);
            xKeyValid[2] = GetDsIpfixL3Ipv6HashKey(V, xKeyValid2_f, p_key);
            xKeyValid[3] = GetDsIpfixL3Ipv6HashKey(V, xKeyValid3_f, p_key);
            if(use_io)
            {
                    p_ad = (DsIpfixSessionRecord_m*)p_buffer_ad;
                    cmdr_ad = DRV_IOR(SYS_IPFIX_GET_TABLE(DsIpfixSessionRecord_t,dir), DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (SYS_IPFIX_GET_ADINDEX(index+ loop*4, dir)), DRV_CMD_PP_EN(cmdr_ad), p_buffer_ad), ret, end_pro);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (SYS_IPFIX_GET_ADINDEX(index+ loop*4+1, dir)), DRV_CMD_PP_EN(cmdr_ad), (DsIpfixSessionRecord_m*)p_buffer_ad+1), ret, end_pro);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (SYS_IPFIX_GET_ADINDEX(index+ loop*4+2, dir)), DRV_CMD_PP_EN(cmdr_ad), (DsIpfixSessionRecord_m*)p_buffer_ad+2), ret, end_pro);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, (SYS_IPFIX_GET_ADINDEX(index+ loop*4+3, dir)), DRV_CMD_PP_EN(cmdr_ad), (DsIpfixSessionRecord_m*)p_buffer_ad+3), ret, end_pro);
            }

            for (sub_idx = idx_left; sub_idx < 4; sub_idx++)
            {
                key_width = _sys_tmm_ipfix_get_key_width(lchip, hash_type[sub_idx]);
                /*xdata_fk*/
                if(xKeyValid[sub_idx])
                {
                    xkey_user_data.key_type = ctc_at_hash_type[hash_type[sub_idx]];
                    xkey_user_data.dir = dir;
                    CTC_ERROR_GOTO(ctc_vector_traverse2(p_usw_ipfix_master[lchip]->flex_key_vec,CTC_IPFIX_KEY_HASH_FLEX_BASE,
                                    _sys_at_ipfix_xkey_vector, (void *)&xkey_user_data), ret, end_pro);
                    if(xkey_user_data.key_type < CTC_IPFIX_KEY_HASH_FLEX_BASE)
                    {
                        ret  = CTC_E_NOT_EXIST;
                        goto end_pro;
                    }
                    key_width = (xkey_user_data.mode == CTC_FIELD_FLEX_KEY_MODE_DOUBLE_APPEND)?(2*key_width):(key_width);
                }
                if((0 == key_width)||(sub_idx % key_width != 0))
                {
                    continue;
                }
                sal_memset(&ipfix_data, 0, sizeof(ctc_ipfix_data_t));
                ipfix_data.key_type = _sys_usw_ipfix_unmapping_key_type(lchip, hash_type[sub_idx]);
                /*xdata_fk*/
                if (xKeyValid[sub_idx])
                {
                    MALLOC_ZERO(MEM_IPFIX_MODULE, ipfix_data.flex_key.field_list, sizeof(ctc_field_key_t)*MAX_XKEY_FIELD_NUM);
                    if (NULL == ipfix_data.flex_key.field_list)
                    {
                        ret  = CTC_E_NO_MEMORY;
                        goto end_pro;
                    }
                    MALLOC_ZERO(MEM_IPFIX_MODULE, ipfix_data.xdata.fields, sizeof(ctc_xdata_field_t)*MAX_XDATA_FIELD_NUM);
                    if (NULL == ipfix_data.xdata.fields)
                    {
                        mem_free(ipfix_data.flex_key.field_list);
                        ret  = CTC_E_NO_MEMORY;
                        goto end_pro;
                    }
                    ipfix_data.key_type = xkey_user_data.key_type;
                    
                }
                ipfix_data.dir = dir;
                ipfix_data.pp_bmp = 1 << (lchip - (SYS_PP_BASE(lchip)));
                sys_at_ipfix_decode_key_ad(lchip, &ipfix_data, 0, (DsIpfixL3Ipv4ShortHashKey_m*)p_key + sub_idx);
                sys_at_ipfix_decode_key_ad(lchip, &ipfix_data, 1, (uint32*)p_ad+sub_idx*ad_size);

                temp_idx = index + loop*4 + sub_idx;
                ipfix_data.key_index = temp_idx;
                dump_info.lchip_id = lchip;
                IPFIX_AT_TRAVERSE_TYPE_PROCESS(dump_info, ipfix_data.key_type, is_remove, dir);
                /*xdata_fk*/
                if(xKeyValid[sub_idx])
                {
                     mem_free(ipfix_data.flex_key.field_list);
                     mem_free(ipfix_data.xdata.fields);
                }
                count += key_width;

                if (count >= p_data->entry_num)
                {
                    next_index = (index + loop*4) + (sub_idx + 1);
                    goto end_pro;
                }
            }
            next_index = (index + loop*4);
            idx_left = 0;
        }
        index += 4*entry_cnt;
        next_index = index;
    }while(index < dump_end_entry_num && count < p_data->entry_num);
end_pro:
    if(index >= ipfix_max_entry_num)
    {
        p_data->is_end = 1;
    }
    p_data->next_traverse_index = next_index;
    if(p_buffer)
    {
        mem_free(p_buffer);
    }
    if(p_buffer_ad)
    {
        mem_free(p_buffer_ad);
    }
    return ret;
}

static INLINE uint32
_sys_at_ipfix_uncombined_key(uint8 lchip, uint32* data_combined, uint32* data, uint32 tbl_id)
{
    if (DsIpfixSessionRecordMem_t == tbl_id)
    {
        CTC_BMP_COPY_RANGE(data, 0, data_combined, 0, 266);
    }
    else if (DsIpfixSessionMmuRecordMem_t == tbl_id)
    {
        sal_memcpy((uint8*)data, data_combined, 15);
    }
    else
    {
        CTC_BMP_COPY_RANGE(data, 0, data_combined, 0, 134);
        CTC_BMP_COPY_RANGE(data, 160, data_combined, 134, 134);
        CTC_BMP_COPY_RANGE(data, 320, data_combined, 268, 134);
        CTC_BMP_COPY_RANGE(data, 480, data_combined, 402, 134);
    }
    return DRV_E_NONE;
}


int32
sys_at_ipfix_sync_data(uint8 lchip, void* p_dma_info)
{
    uint32 entry_num = 0;
    uint16 index = 0;
    uint16 loop = 0;
    uint8 tmp_reason=0;
    ds_t ds_temp;
    uint8 tmp_lchip = 0;
    sys_dma_info_t* p_info = (sys_dma_info_t*)p_dma_info;
    MsIpfixDmaInfo_m* p_temp_fifo = NULL;
    CpuInfoIpfix_m* p_ipfix_cpu_info = NULL;
    void *user_data = NULL;  /* per 64 entry call user callback function */
    ds_t hash_key;
    ds_t ipfix_ad;
    ds_t ipfix_mmu_ad;
    uint8 dump_fixed_mode = 0;
    ctc_ipfix_data_t* user_info = NULL;
    ctc_ipfix_data_t* user_info_next = NULL;
    ctc_field_key_t* p_field_list = NULL;
    ctc_xdata_field_t* p_xdata_list = NULL;
    int32 ret = CTC_E_NONE;
    entry_num = p_info->entry_num;
    if (p_ipfix_cb_mutex)
    {
        sal_mutex_lock(p_ipfix_cb_mutex);
    }
    for (index = 0; index < entry_num; index++)
    {
        p_ipfix_cpu_info = (CpuInfoIpfix_m*)((uint8*)p_info->p_data + index * TABLE_ENTRY_SIZE(lchip, CpuInfoIpfix_t));
        p_temp_fifo = (MsIpfixDmaInfo_m*)((uint8*)p_ipfix_cpu_info + SYS_USW_DMA_INFO_OFFSET);
        tmp_reason =ctc_at_export_reason[((*(uint32*)p_temp_fifo)>>1)&0x1F];
        tmp_lchip = (((*(uint32*)p_ipfix_cpu_info) >> 24)&0x3) + (p_info->base_lchip);/*ppid*/
        p_usw_ipfix_master[SYS_PP_BASE(tmp_lchip)]->cb_buf_status = 1;
        SYS_IPFIX_LOCK(tmp_lchip);
        user_data = p_usw_ipfix_master[tmp_lchip]->cb_buf;  /* per 64 entry call user callback function */
        user_info = (ctc_ipfix_data_t*)((uint8*)user_data + (sizeof(ctc_ipfix_data_t)+sizeof(ctc_field_key_t)*MAX_XKEY_FIELD_NUM + sizeof(ctc_xdata_field_t)*MAX_XDATA_FIELD_NUM)*loop);
        p_xdata_list = (ctc_xdata_field_t*)((uint8*)user_info + sizeof(ctc_ipfix_data_t) + sizeof(ctc_field_key_t)*MAX_XKEY_FIELD_NUM);
        p_field_list = (ctc_field_key_t*)((uint8*)user_info + sizeof(ctc_ipfix_data_t));
        sal_memset(user_info, 0, sizeof(ctc_ipfix_data_t));
        sal_memset(p_field_list, 0, sizeof(ctc_field_key_t));
        sal_memset(p_xdata_list, 0, sizeof(ctc_xdata_field_t));
        user_info->pp_bmp = (1 << (tmp_lchip-SYS_PP_BASE(tmp_lchip)));
        user_info->key_index = ((*(uint32*)p_temp_fifo)>>6)&0x3FFFF;

        if (tmp_reason == CTC_IPFIX_REASON_DUMP && p_usw_ipfix_master[tmp_lchip]->dump_num)
        {
            p_usw_ipfix_master[tmp_lchip]->dump_num --;
            dump_fixed_mode = 1;
        }
        else if (tmp_reason == CTC_IPFIX_REASON_DUMP && dump_fixed_mode)
        {
            SYS_IPFIX_UNLOCK(tmp_lchip);
            continue;
        }
        user_info->dir = (*(uint32*)p_temp_fifo)&0x1;
        GetMsIpfixDmaInfo(A, ipfixHashKey_f, p_temp_fifo, &ds_temp);
        _sys_at_ipfix_uncombined_key(tmp_lchip, (uint32*)ds_temp, (uint32*)&hash_key, DsIpfixL2L3HashKey_t);
        GetMsIpfixDmaInfo(A, ipfixAd_f, p_temp_fifo, &ds_temp);
        _sys_at_ipfix_uncombined_key(tmp_lchip, (uint32*)ds_temp, (uint32*)&ipfix_ad, DsIpfixSessionRecordMem_t);
        user_info->export_reason = ctc_at_export_reason[((*(uint32*)p_temp_fifo)>>1)&0x1F];
        if (user_info->dir == CTC_INGRESS)
        {
            GetMsIpfixDmaInfo(A, ipfixMmuAd_f, p_temp_fifo, &ds_temp);
            _sys_at_ipfix_uncombined_key(tmp_lchip, (uint32*)ds_temp, (uint32*)&ipfix_mmu_ad, DsIpfixSessionMmuRecordMem_t);
        }
        user_info->key_type = ctc_at_hash_type[hash_key[0]&0xF];
        user_info->flex_key.field_list = p_field_list;
        user_info->xdata.fields = p_xdata_list;
        sys_at_ipfix_decode_key_ad(tmp_lchip, user_info, 0, &hash_key);
        sys_at_ipfix_decode_key_ad(tmp_lchip, user_info, 1, &ipfix_ad);

        if (user_info->dir == CTC_INGRESS)
        {
            sys_at_ipfix_decode_key_ad(tmp_lchip, user_info, 2, &ipfix_mmu_ad);
        }

        _sys_usw_ipfix_export_stats(tmp_lchip, user_info->export_reason, user_info->pkt_count, user_info->byte_count);
        SYS_IPFIX_UNLOCK(tmp_lchip);

        if (p_usw_ipfix_master[tmp_lchip]->max_export_entry_num == (loop+1))
        {
            user_info->p_next = NULL;
            if (!(p_usw_ipfix_master[tmp_lchip]->ipfix_cb))
            {
                ret = CTC_E_NO_MEMORY;
                goto end_pro;
            }

            p_usw_ipfix_master[tmp_lchip]->ipfix_cb((ctc_ipfix_data_t*)user_data, p_usw_ipfix_master[tmp_lchip]->user_data);
            loop = 0;
        }
        else
        {
              user_info_next = (ctc_ipfix_data_t*)((uint8*)user_info + (sizeof(ctc_ipfix_data_t)+sizeof(ctc_field_key_t)*MAX_XKEY_FIELD_NUM + sizeof(ctc_xdata_field_t)*MAX_XDATA_FIELD_NUM));
              user_info->p_next = user_info_next;
              loop++;
        }

    }

    if(loop)
    {
        user_info->p_next = NULL;
        if (!(p_usw_ipfix_master[tmp_lchip]->ipfix_cb))
        {
            ret = CTC_E_NO_MEMORY;
            goto end_pro;
        }
        p_usw_ipfix_master[tmp_lchip]->ipfix_cb((ctc_ipfix_data_t*)user_data, p_usw_ipfix_master[tmp_lchip]->user_data);

    }
end_pro:
    p_usw_ipfix_master[SYS_PP_BASE(tmp_lchip)]->cb_buf_status = 0;
    if (p_ipfix_cb_mutex)
    {
        sal_mutex_unlock(p_ipfix_cb_mutex);
    }        

    return ret;
}

int32
sys_at_ipfix_cb_init(uint8 lchip)
{
    /*encode*/
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_encode_l2_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_encode_l2l3_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_encode_ipv4_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV6] = _sys_usw_ipfix_encode_ipv6_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_MPLS] = _sys_usw_ipfix_encode_mpls_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_UDF] = _sys_at_ipfix_encode_udf_key;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_UDF_SINGLE] = _sys_at_ipfix_encode_udf_short_key;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV4_SINGLE] = _sys_at_ipfix_encode_v4_short_key;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_IPV6_SINGLE] = _sys_at_ipfix_encode_v6_short_key;
    p_usw_ipfix_master[lchip]->callbacks_encode[CTC_IPFIX_KEY_HASH_MPLS_SINGLE] = _sys_at_ipfix_encode_v4_short_key;

    /*decode*/
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_MAC] = _sys_at_ipfix_decode_l2_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_at_ipfix_decode_l2l3_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV4] = _sys_at_ipfix_decode_ipv4_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV6] = _sys_at_ipfix_decode_ipv6_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_MPLS] = _sys_at_ipfix_decode_mpls_hashkey;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_UDF] = _sys_at_ipfix_decode_udf_key;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_UDF_SINGLE] = _sys_at_ipfix_decode_udf_short_key;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV4_SINGLE] = _sys_at_ipfix_decode_v4_short_key;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_IPV6_SINGLE] = _sys_at_ipfix_decode_v6_short_key;
    p_usw_ipfix_master[lchip]->callbacks_decode[CTC_IPFIX_KEY_HASH_MPLS_SINGLE] = _sys_at_ipfix_decode_v4_short_key;

    /*set hash select*/
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_set_l2_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_set_l2l3_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_set_ipv4_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV6] = _sys_usw_ipfix_set_ipv6_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_MPLS] = _sys_usw_ipfix_set_mpls_hash_field_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_UDF] = _sys_at_ipfix_set_udf_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_UDF_SINGLE] = _sys_at_ipfix_set_short_udf_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV4_SINGLE] = _sys_tmm_ipfix_set_v4_short_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_IPV6_SINGLE] = _sys_tmm_ipfix_set_v6_short_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_set_hashsel[CTC_IPFIX_KEY_HASH_MPLS_SINGLE] = _sys_tmm_ipfix_set_v4_short_hash_sel;

    /*get hash select*/
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_MAC] = _sys_usw_ipfix_get_mac_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_L2_L3] = _sys_usw_ipfix_get_l2l3_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV4] = _sys_usw_ipfix_get_v4_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV6] = _sys_usw_ipfix_get_v6_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_MPLS] = _sys_usw_ipfix_get_mpls_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_UDF] = _sys_at_ipfix_get_udf_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_UDF_SINGLE] = _sys_at_ipfix_get_udf_short_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV4_SINGLE] = _sys_at_ipfix_get_v4_short_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_IPV6_SINGLE] = _sys_at_ipfix_get_v6_short_hash_sel;
    p_usw_ipfix_master[lchip]->callbacks_get_hashsel[CTC_IPFIX_KEY_HASH_MPLS_SINGLE] = _sys_at_ipfix_get_mpls_short_hash_sel;

    return CTC_E_NONE;
}

#endif
#endif

